diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/npc.cpp | 55 | ||||
-rw-r--r-- | src/ast/npc.hpp | 11 | ||||
-rw-r--r-- | src/ast/npc_test.cpp | 68 | ||||
-rw-r--r-- | src/map/chrif.cpp | 5 | ||||
-rw-r--r-- | src/map/clif.cpp | 33 | ||||
-rw-r--r-- | src/map/npc-parse.cpp | 122 | ||||
-rw-r--r-- | src/map/npc.cpp | 2 | ||||
-rw-r--r-- | src/map/pc.cpp | 29 | ||||
-rw-r--r-- | src/map/pc.hpp | 1 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 27 | ||||
-rw-r--r-- | src/monitor/fwd.hpp | 37 | ||||
-rw-r--r-- | src/monitor/globals.cpp | 33 | ||||
-rw-r--r-- | src/monitor/globals.hpp | 33 | ||||
-rw-r--r-- | src/monitor/main.cpp | 243 |
14 files changed, 51 insertions, 648 deletions
diff --git a/src/ast/npc.cpp b/src/ast/npc.cpp index e9c3464..8d4a43e 100644 --- a/src/ast/npc.cpp +++ b/src/ast/npc.cpp @@ -306,7 +306,7 @@ namespace npc static Result<ScriptNone> parse_script_none_head(io::LineSpan span, std::vector<Spanned<std::vector<Spanned<RString>>>>& bits) { - // ScriptNone: -|script|script name|-1{code} + // ScriptNone: -|script|script name|32767{code} if (bits.size() != 4) { return Err(span.error_str("expect 4 |component|s"_s)); @@ -319,10 +319,10 @@ namespace npc { return Err(bits[2].span.error_str("in |component 3| expect 1 ,component,s"_s)); } - assert(bits[3].data[0].data == "-1"_s); + assert(bits[3].data[0].data == "32767"_s); if (bits[3].data.size() != 1) { - return Err(bits[3].span.error_str("in |component 4| should be just -1"_s)); + return Err(bits[3].span.error_str("in |component 4| should be just 32767"_s)); } ScriptNone script_none; @@ -333,39 +333,6 @@ namespace npc return Ok(std::move(script_none)); } static - Result<ScriptMapNone> parse_script_map_none_head(io::LineSpan span, std::vector<Spanned<std::vector<Spanned<RString>>>>& bits) - { - // ScriptMapNone: m,x,y,d|script|script name|-1{code} - if (bits.size() != 4) - { - return Err(span.error_str("expect 4 |component|s"_s)); - } - if (bits[0].data.size() != 4) - { - return Err(bits[0].span.error_str("in |component 1| expect 3 ,component,s"_s)); - } - assert(bits[1].data.size() == 1); - assert(bits[1].data[0].data == "script"_s); - if (bits[2].data.size() != 1) - { - return Err(bits[2].span.error_str("in |component 3| expect 1 ,component,s"_s)); - } - if (bits[3].data.size() != 1 || bits[3].data[0].data != "-1"_s) - { - return Err(bits[3].span.error_str("in |component 4| should be just -1"_s)); - } - - ScriptMapNone script_map_none; - TRY_EXTRACT(bits[0].data[0], script_map_none.m); - TRY_EXTRACT(bits[0].data[1], script_map_none.x); - TRY_EXTRACT(bits[0].data[2], script_map_none.y); - TRY_EXTRACT(bits[0].data[3], script_map_none.d); - TRY_EXTRACT(bits[2].data[0], script_map_none.name); - script_map_none.key4_span = bits[3].data[0].span; - // also expect '{' and parse real script (in caller) - return Ok(std::move(script_map_none)); - } - static Result<ScriptMap> parse_script_map_head(io::LineSpan span, std::vector<Spanned<std::vector<Spanned<RString>>>>& bits) { // ScriptMap: m,x,y,d|script|script name|class,xs,ys{code} @@ -417,10 +384,9 @@ namespace npc static Result<Script> parse_script_any(io::LineSpan span, std::vector<Spanned<std::vector<Spanned<RString>>>>& bits, io::LineCharReader& lr) { - // 4 cases: + // 3 cases: // ScriptFunction: function|script|Fun Name{code} - // ScriptNone: -|script|script name|-1{code} - // ScriptMapNone: m,x,y,d|script|script name|-1{code} + // ScriptNone: -|script|script name|32767{code} // ScriptMap: m,x,y,d|script|script name|class,xs,ys{code} if (bits[0].data[0].data == "function"_s) { @@ -445,17 +411,6 @@ namespace npc rv.body = TRY(ast::script::parse_script_body(lr, opt)); return Ok(std::move(rv)); } - else if (bits.size() >= 4 && bits[3].data[0].data == "-1"_s) - { - Script rv = TRY(parse_script_map_none_head(span, bits)); - rv.key_span = bits[1].data[0].span; - - ast::script::ScriptOptions opt; - opt.implicit_start = true; - opt.no_start = true; - rv.body = TRY(ast::script::parse_script_body(lr, opt)); - return Ok(std::move(rv)); - } else { ScriptMap script_map = TRY(parse_script_map_head(span, bits)); diff --git a/src/ast/npc.hpp b/src/ast/npc.hpp index a51acd3..ca6479e 100644 --- a/src/ast/npc.hpp +++ b/src/ast/npc.hpp @@ -103,14 +103,6 @@ namespace npc Spanned<NpcName> name; io::LineSpan key4_span; }; - struct ScriptMapNone - { - Spanned<MapName> m; - Spanned<unsigned> x, y; - Spanned<DIR> d; - Spanned<NpcName> name; - io::LineSpan key4_span; - }; struct ScriptMap { Spanned<MapName> m; @@ -120,13 +112,12 @@ namespace npc Spanned<Species> npc_class; Spanned<unsigned> xs, ys; }; - using ScriptBase = Variant<ScriptFunction, ScriptNone, ScriptMapNone, ScriptMap>; + using ScriptBase = Variant<ScriptFunction, ScriptNone, ScriptMap>; struct Script : ScriptBase { Script() = default; Script(ScriptFunction s) : ScriptBase(std::move(s)) {} Script(ScriptNone s) : ScriptBase(std::move(s)) {} - Script(ScriptMapNone s) : ScriptBase(std::move(s)) {} Script(ScriptMap s) : ScriptBase(std::move(s)) {} io::LineSpan key_span; diff --git a/src/ast/npc_test.cpp b/src/ast/npc_test.cpp index a753623..dadeba7 100644 --- a/src/ast/npc_test.cpp +++ b/src/ast/npc_test.cpp @@ -423,11 +423,11 @@ namespace npc { // 1 2 3 //23456789012345678901234567890123456789 - "-|script|#config|-1{end;}"_s, + "-|script|#config|32767{end;}"_s, // 123456 - "-|script|#config|-1\n{end;}\n"_s, + "-|script|#config|32767\n{end;}\n"_s, // 1234567 - "-|script|#config|-1\n \n {end;} "_s, + "-|script|#config|32767\n \n {end;} "_s, }; for (auto input : inputs) { @@ -435,7 +435,7 @@ namespace npc auto res = TRY_UNWRAP(parse_top(lr), FAIL()); EXPECT_TRUE(res.get_success().is_some()); auto top = TRY_UNWRAP(std::move(res.get_success()), FAIL()); - EXPECT_SPAN(top.span, 1,1, 1,19); + EXPECT_SPAN(top.span, 1,1, 1,22); auto script = top.get_if<Script>(); EXPECT_TRUE(script); auto p = script->get_if<ScriptNone>(); @@ -446,66 +446,10 @@ namespace npc EXPECT_SPAN(script->key_span, 1,3, 1,8); EXPECT_SPAN(p->name.span, 1,10, 1,16); EXPECT_EQ(p->name.data, stringish<NpcName>("#config"_s)); - EXPECT_SPAN(p->key4_span, 1,18, 1,19); + EXPECT_SPAN(p->key4_span, 1,18, 1,22); if (input.endswith('}')) { - EXPECT_SPAN(script->body.span, 1,20, 1,25); - } - else if (input.endswith('\n')) - { - EXPECT_SPAN(script->body.span, 2,1, 2,6); - } - else if (input.endswith(' ')) - { - EXPECT_SPAN(script->body.span, 3,2, 3,7); - } - else - { - FAIL(); - } - EXPECT_EQ(script->body.braced_body, "{end;}"_s); - } - } - } - TEST(npcast, scriptmapnone) - { - QuietFd q; - LString inputs[] = - { - // 1 2 3 - //23456789012345678901234567890123456789 - "map.gat,1,2,3|script|Init|-1{end;}"_s, - "map.gat,1,2,3|script|Init|-1\n{end;}\n"_s, - "map.gat,1,2,3|script|Init|-1\n \n {end;} "_s, - }; - for (auto input : inputs) - { - io::LineCharReader lr(io::from_string, "<string>"_s, input); - auto res = TRY_UNWRAP(parse_top(lr), FAIL()); - EXPECT_TRUE(res.get_success().is_some()); - auto top = TRY_UNWRAP(std::move(res.get_success()), FAIL()); - EXPECT_SPAN(top.span, 1,1, 1,28); - auto script = top.get_if<Script>(); - EXPECT_TRUE(script); - auto p = script->get_if<ScriptMapNone>(); - EXPECT_TRUE(p); - if (p) - { - EXPECT_SPAN(p->m.span, 1,1, 1,7); - EXPECT_EQ(p->m.data, stringish<MapName>("map"_s)); - EXPECT_SPAN(p->x.span, 1,9, 1,9); - EXPECT_EQ(p->x.data, 1); - EXPECT_SPAN(p->y.span, 1,11, 1,11); - EXPECT_EQ(p->y.data, 2); - EXPECT_SPAN(p->d.span, 1,13, 1,13); - EXPECT_EQ(p->d.data, DIR::NW); - EXPECT_SPAN(script->key_span, 1,15, 1,20); - EXPECT_SPAN(p->name.span, 1,22, 1,25); - EXPECT_EQ(p->name.data, stringish<NpcName>("Init"_s)); - EXPECT_SPAN(p->key4_span, 1,27, 1,28); - if (input.endswith('}')) - { - EXPECT_SPAN(script->body.span, 1,29, 1,34); + EXPECT_SPAN(script->body.span, 1,23, 1,28); } else if (input.endswith('\n')) { diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index 37efc4e..2606911 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -249,11 +249,6 @@ int chrif_connectack(Session *s, const Packet_Fixed<0x2af9>& fixed) chrif_sendmap(s); - PRINTF("chrif: OnCharIfInit event done. (%d events)\n"_fmt, - npc_event_doall(stringish<ScriptLabel>("OnCharIfInit"_s))); - PRINTF("chrif: OnInterIfInit event done. (%d events)\n"_fmt, - npc_event_doall(stringish<ScriptLabel>("OnInterIfInit"_s))); - return 0; } diff --git a/src/map/clif.cpp b/src/map/clif.cpp index e3cd55f..d327286 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -807,6 +807,8 @@ void clif_mob007b(dumb_ptr<mob_data> md, Buffer& buf) fixed_7b.mob_class = md->mob_class; // snip: stuff for monsters disguised as PCs fixed_7b.tick_and_maybe_part_of_guild_emblem = gettick(); + fixed_7b.max_hp = md->stats[mob_stat::MAX_HP]; + fixed_7b.hp = md->hp; fixed_7b.pos2.x0 = md->bl_x; fixed_7b.pos2.y0 = md->bl_y; @@ -819,7 +821,33 @@ void clif_mob007b(dumb_ptr<mob_data> md, Buffer& buf) buf = create_fpacket<0x007b, 60>(fixed_7b); } +/*========================================== + * Packet to send server's mob walkpath data + *------------------------------------------ + */ +static +int clif_0225_being_move3(dumb_ptr<mob_data> md) +{ + Packet_Head<0x0225> head_225; + std::vector<Packet_Repeat<0x0225>> repeat_225; + + head_225.magic_packet_length = md->walkpath.path_len + 14; + head_225.id = md->bl_id; + head_225.speed = battle_get_speed(md); + head_225.x_position = md->bl_x; + head_225.y_position = md->bl_y; + for (int i = 0; i < md->walkpath.path_len; i++) + { + Packet_Repeat<0x0225> move_225; + move_225.move = md->walkpath.path[i]; + repeat_225.push_back(move_225); + } + + Buffer buf = create_vpacket<0x0225, 14, 1>(head_225, repeat_225); + clif_send(buf, md, SendWho::AREA); + return 0; +} /*========================================== * *------------------------------------------ @@ -901,7 +929,7 @@ int clif_spawnnpc(dumb_ptr<npc_data> nd) { nullpo_retz(nd); - if (nd->npc_class == NEGATIVE_SPECIES || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) + if (nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) return 0; Packet_Fixed<0x007c> fixed_7c; @@ -2320,7 +2348,7 @@ void clif_getareachar_npc(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd) nullpo_retv(sd); nullpo_retv(nd); - if (nd->npc_class == NEGATIVE_SPECIES || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) + if (nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) return; Buffer buf; @@ -2339,6 +2367,7 @@ int clif_movemob(dumb_ptr<mob_data> md) Buffer buf; clif_mob007b(md, buf); clif_send(buf, md, SendWho::AREA); + clif_0225_being_move3(md); return 0; } diff --git a/src/map/npc-parse.cpp b/src/map/npc-parse.cpp index 9c9a22c..4d9fcbd 100644 --- a/src/map/npc-parse.cpp +++ b/src/map/npc-parse.cpp @@ -446,7 +446,7 @@ bool npc_load_script_none(ast::script::ScriptBody& body, ast::npc::ScriptNone& s nd->bl_id = npc_get_new_npc_id(); nd->dir = DIR::S; nd->flag = 0; - nd->npc_class = NEGATIVE_SPECIES; + nd->npc_class = INVISIBLE_CLASS; nd->speed = 200_ms; nd->scr.script = std::move(script); nd->option = Opt0::ZERO; @@ -514,115 +514,6 @@ bool npc_load_script_none(ast::script::ScriptBody& body, ast::npc::ScriptNone& s } static -bool npc_load_script_map_none(ast::script::ScriptBody& body, ast::npc::ScriptMapNone& script_map_none) -{ - MapName mapname = script_map_none.m.data; - int x = script_map_none.x.data, y = script_map_none.y.data; - DIR dir = script_map_none.d.data; - P<map_local> m = TRY_UNWRAP(map_mapname2mapid(mapname), - { - script_map_none.m.span.error("No such map"_s); - return false; - }); - - std::unique_ptr<const ScriptBuffer> script = compile_script(STRPRINTF("script npc \"%s\""_fmt, script_map_none.name.data), body, false); - if (script == nullptr) - return false; - - dumb_ptr<npc_data_script> nd; - nd.new_(); - nd->scr.event_needs_map = false; - - nd->name = script_map_none.name.data; - - nd->bl_prev = nd->bl_next = nullptr; - nd->bl_m = m; - nd->bl_x = x; - nd->bl_y = y; - nd->bl_id = npc_get_new_npc_id(); - nd->dir = dir; - nd->flag = 0; - nd->npc_class = NEGATIVE_SPECIES; - nd->speed = 200_ms; - nd->scr.script = std::move(script); - nd->option = Opt0::ZERO; - nd->opt1 = Opt1::ZERO; - nd->opt2 = Opt2::ZERO; - nd->opt3 = Opt3::ZERO; - - npc_script++; - nd->bl_type = BL::NPC; - nd->npc_subtype = NpcSubtype::SCRIPT; - - nd->n = map_addnpc(m, nd); - map_addblock(nd); - - { - struct event_data ev {}; - ev.nd = nd; - ev.pos = 0; - NpcEvent npcev; - npcev.npc = nd->name; - npcev.label = ScriptLabel(); - ev_db.insert(npcev, ev); - } - - register_npc_name(nd); - - for (auto& pair : scriptlabel_db) - npc_convertlabel_db(pair.first, pair.second, nd); - - for (npc_label_list& el : nd->scr.label_listv) - { - ScriptLabel lname = el.name; - int pos = el.pos; - - if (lname.startswith("On"_s)) - { - struct event_data ev {}; - ev.nd = nd; - ev.pos = pos; - NpcEvent buf; - buf.npc = nd->name; - buf.label = lname; - ev_db.insert(buf, ev); - } - } - - for (npc_label_list& el : nd->scr.label_listv) - { - int t_ = 0; - ScriptLabel lname = el.name; - int pos = el.pos; - if (lname.startswith("OnTimer"_s) && extract(lname.xslice_t(7), &t_) && t_ > 0) - { - interval_t t = static_cast<interval_t>(t_); - - npc_timerevent_list tel {}; - tel.timer = t; - tel.pos = pos; - - auto it = std::lower_bound(nd->scr.timer_eventv.begin(), nd->scr.timer_eventv.end(), tel, - [](const npc_timerevent_list& l, const npc_timerevent_list& r) - { - return l.timer < r.timer; - } - ); - assert (it == nd->scr.timer_eventv.end() || it->timer != tel.timer); - - nd->scr.timer_eventv.insert(it, std::move(tel)); - } - } - // The counter starts stopped with 0 ticks, which is the first event, - // unless there is none, in which case begin == end. - nd->scr.timer = interval_t::zero(); - nd->scr.next_event = nd->scr.timer_eventv.begin(); - // nd->scr.timerid = nullptr; - - return true; -} - -static bool npc_load_script_map(ast::script::ScriptBody& body, ast::npc::ScriptMap& script_map) { MapName mapname = script_map.m.data; @@ -761,17 +652,6 @@ bool npc_load_script_any(ast::npc::Script *script) { return npc_load_script_none(script->body, script_none); } - MATCH_CASE (ast::npc::ScriptMapNone&, script_map_none) - { - auto& mapname = script_map_none.m; - Option<P<map_local>> m = map_mapname2mapid(mapname.data); - if (m.is_none()) - { - mapname.span.error(STRPRINTF("Map not found: %s"_fmt, mapname.data)); - return false; - } - return npc_load_script_map_none(script->body, script_map_none); - } MATCH_CASE (ast::npc::ScriptMap&, script_map) { auto& mapname = script_map.m; diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 56c33cc..4296432 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -583,7 +583,7 @@ int npc_checknear(dumb_ptr<map_session_data> sd, BlockId id) if (nd->bl_type != BL::NPC) return 1; - if (nd->npc_class == NEGATIVE_SPECIES) + if (nd->npc_class == INVISIBLE_CLASS) return 0; // エリア判定 diff --git a/src/map/pc.cpp b/src/map/pc.cpp index e8e526a..6fa35b0 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -2289,35 +2289,6 @@ int pc_setpos(dumb_ptr<map_session_data> sd, } /*========================================== - * PCのランダムワープ - *------------------------------------------ - */ -int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type) -{ - int x, y, i = 0; - - nullpo_retz(sd); - - P<map_local> m = sd->bl_m; - - if (sd->bl_m->flag.get(MapFlag::NOTELEPORT)) // テレポート禁止 - return 0; - - do - { - x = random_::in(1, m->xs - 2); - y = random_::in(1, m->ys - 2); - } - while (bool(read_gatp(m, x, y) & MapCell::UNWALKABLE) - && (i++) < 1000); - - if (i < 1000) - pc_setpos(sd, m->name_, x, y, type); - - return 0; -} - -/*========================================== * *------------------------------------------ */ diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 6c0803f..d100938 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -92,7 +92,6 @@ int pc_walktoxy(dumb_ptr<map_session_data>, int, int); int pc_stop_walking(dumb_ptr<map_session_data>, int); int pc_setpos(dumb_ptr<map_session_data>, MapName, int, int, BeingRemoveWhy); void pc_setsavepoint(dumb_ptr<map_session_data>, MapName, int, int); -int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type); ADDITEM pc_checkadditem(dumb_ptr<map_session_data>, ItemNameId, int); int pc_inventoryblank(dumb_ptr<map_session_data>); diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 6dc1510..4c20555 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -358,22 +358,10 @@ void builtin_warp(ScriptState *st) { int x, y; dumb_ptr<map_session_data> sd = script_rid2sd(st); - MapName str = stringish<MapName>(ZString(conv_str(st, &AARG(0)))); x = conv_num(st, &AARG(1)); y = conv_num(st, &AARG(2)); - if (str == "Random"_s) - pc_randomwarp(sd, BeingRemoveWhy::WARPED); - else if (str == "SavePoint"_s or str == "Save"_s) - { - if (sd->bl_m->flag.get(MapFlag::NORETURN)) - return; - - pc_setpos(sd, sd->status.save_point.map_, sd->status.save_point.x, sd->status.save_point.y, - BeingRemoveWhy::WARPED); - } - else - pc_setpos(sd, str, x, y, BeingRemoveWhy::GONE); + pc_setpos(sd, str, x, y, BeingRemoveWhy::GONE); } /*========================================== @@ -384,10 +372,7 @@ static void builtin_areawarp_sub(dumb_ptr<block_list> bl, MapName mapname, int x, int y) { dumb_ptr<map_session_data> sd = bl->is_player(); - if (mapname == "Random"_s) - pc_randomwarp(sd, BeingRemoveWhy::WARPED); - else - pc_setpos(sd, mapname, x, y, BeingRemoveWhy::GONE); + pc_setpos(sd, mapname, x, y, BeingRemoveWhy::GONE); } static @@ -3132,11 +3117,11 @@ BuiltinFunction builtin_functions[] = BUILTIN(killmonster, "ME"_s, '\0'), BUILTIN(donpcevent, "E"_s, '\0'), BUILTIN(addtimer, "tE"_s, '\0'), - BUILTIN(initnpctimer, ""_s, '\0'), + BUILTIN(initnpctimer, "?"_s, '\0'), BUILTIN(startnpctimer, "?"_s, '\0'), - BUILTIN(stopnpctimer, ""_s, '\0'), - BUILTIN(getnpctimer, "i"_s, 'i'), - BUILTIN(setnpctimer, "i"_s, '\0'), + BUILTIN(stopnpctimer, "?"_s, '\0'), + BUILTIN(getnpctimer, "i?"_s, 'i'), + BUILTIN(setnpctimer, "i?"_s, '\0'), BUILTIN(announce, "si"_s, '\0'), BUILTIN(mapannounce, "Msi"_s, '\0'), BUILTIN(getusers, "i"_s, 'i'), diff --git a/src/monitor/fwd.hpp b/src/monitor/fwd.hpp deleted file mode 100644 index 6900e8e..0000000 --- a/src/monitor/fwd.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -// monitor/fwd.hpp - list of type names for monitor nonserver -// -// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "../sanity.hpp" - -#include "../strings/fwd.hpp" // rank 1 -#include "../io/fwd.hpp" // rank 4 -#include "../net/fwd.hpp" // rank 5 -#include "../mmo/fwd.hpp" // rank 6 -#include "../high/fwd.hpp" // rank 9 -// monitor/fwd.hpp is rank ∞ because it is an executable - - -namespace tmwa -{ -namespace monitor -{ - struct MonitorConf; -} // namespace monitor -} // namespace tmwa diff --git a/src/monitor/globals.cpp b/src/monitor/globals.cpp deleted file mode 100644 index 49e814d..0000000 --- a/src/monitor/globals.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "globals.hpp" -// globals.cpp - Evil global variables for tmwa-monitor. -// -// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "monitor_conf.hpp" - -#include "../poison.hpp" - - -namespace tmwa -{ - namespace monitor - { - MonitorConf monitor_conf; - pid_t pid_login, pid_char, pid_map; - } // namespace monitor -} // namespace tmwa diff --git a/src/monitor/globals.hpp b/src/monitor/globals.hpp deleted file mode 100644 index aa797d3..0000000 --- a/src/monitor/globals.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -// globals.hpp - Evil global variables for tmwa-monitor. -// -// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "fwd.hpp" - -#include <sys/types.h> - - -namespace tmwa -{ - namespace monitor - { - extern MonitorConf monitor_conf; - extern pid_t pid_login, pid_char, pid_map; - } // namespace monitor -} // namespace tmwa diff --git a/src/monitor/main.cpp b/src/monitor/main.cpp deleted file mode 100644 index f21a4a7..0000000 --- a/src/monitor/main.cpp +++ /dev/null @@ -1,243 +0,0 @@ -// monitor/main.cpp - Old daemon to restart servers when they crashed. -// -// Copyright © ???? Bartosz Waszak <waszi@evil.org.pl> -// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include <sys/wait.h> - -#include <fcntl.h> -#include <unistd.h> - -#include <csignal> -#include <cstdlib> - -#include "../strings/mstring.hpp" -#include "../strings/astring.hpp" -#include "../strings/zstring.hpp" -#include "../strings/xstring.hpp" -#include "../strings/literal.hpp" - -#include "../io/cxxstdio.hpp" -#include "../io/fd.hpp" -#include "../io/line.hpp" - -#include "../mmo/config_parse.hpp" -#include "../mmo/version.hpp" - -#include "../net/timestamp-utils.hpp" - -#include "globals.hpp" -#include "monitor_conf.hpp" - -#include "../poison.hpp" - - -namespace tmwa -{ -namespace monitor -{ -static -AString make_path(XString base, XString path) -{ - MString m; - m += base; - m += '/'; - m += path; - return AString(m); -} - -static -pid_t start_process(ZString exec) -{ - const char *args[2] = {exec.c_str(), nullptr}; - pid_t pid = fork(); - if (pid == -1) - { - FPRINTF(stderr, "Failed to fork"_fmt); - return 0; - } - if (pid == 0) - { - DIAG_PUSH(); - DIAG_I(cast_qual); - execv(exec.c_str(), const_cast<char **>(args)); - DIAG_POP(); - perror("Failed to exec"); - kill(getppid(), SIGABRT); - exit(1); - } - return pid; -} - -// Kill all children with the same signal we got, then ourself. -static -void stop_process(int sig) -{ - if (pid_login) - kill(pid_login, sig); - if (pid_char) - kill(pid_char, sig); - if (pid_map) - kill(pid_map, sig); - DIAG_PUSH(); - DIAG_I(old_style_cast); - DIAG_I(zero_as_null_pointer_constant); - signal(sig, SIG_DFL); - DIAG_POP(); - raise(sig); -} - -static -bool monitor_config(io::Spanned<XString> key, io::Spanned<ZString> value) -{ - return parse_monitor_conf(monitor_conf, key, value); -} - -static -bool monitor_confs(io::Spanned<XString> key, io::Spanned<ZString> value) -{ - if (key.data == "monitor_conf"_s) - { - return load_config_file(value.data, monitor_config); - } - key.span.error("Unknown meta-key for monitor nonserver"_s); - return false; -} -} // namespace monitor -} // namespace tmwa - -int main(int argc, char *argv[]) -{ - using namespace tmwa; - using namespace tmwa::monitor; - // These are all the signals we are likely to get - // The shell handles stop/cont - signal(SIGTERM, stop_process); - signal(SIGINT, stop_process); - signal(SIGQUIT, stop_process); - signal(SIGABRT, stop_process); - - monitor_conf.workdir = make_path(ZString(strings::really_construct_from_a_pointer, getenv("HOME"), nullptr), "tmwserver"_s); - - ZString argv0 = ZString(strings::really_construct_from_a_pointer, argv[0], nullptr); - bool loaded_config_yet = false; - bool runflag = true; - - for (int ai = 1; ai < argc; ++ai) - { - ZString argvi = ZString(strings::really_construct_from_a_pointer, argv[ai], nullptr); - if (argvi.startswith('-')) - { - if (argvi == "--help"_s) - { - PRINTF("Usage: %s [--help] [--version] [files...]\n"_fmt, - argv0); - exit(0); - } - else if (argvi == "--version"_s) - { - PRINTF("%s\n"_fmt, CURRENT_VERSION_STRING); - exit(0); - } - else - { - FPRINTF(stderr, "Unknown argument: %s\n"_fmt, argvi); - runflag = false; - } - } - else - { - loaded_config_yet = true; - runflag &= load_config_file(argvi, monitor_confs); - } - } - - if (!loaded_config_yet) - runflag &= load_config_file("conf/tmwa-monitor.conf"_s, monitor_confs); - - if (!runflag) - exit(1); - - if (chdir(monitor_conf.workdir.c_str()) < 0) - { - perror("Failed to change directory"); - exit(1); - } - - PRINTF("Starting:\n"_fmt); - PRINTF("* workdir: %s\n"_fmt, monitor_conf.workdir); - PRINTF("* login_server: %s\n"_fmt, monitor_conf.login_server); - PRINTF("* char_server: %s\n"_fmt, monitor_conf.char_server); - PRINTF("* map_server: %s\n"_fmt, monitor_conf.map_server); - { - //make sure all possible file descriptors are free for use by the servers - //if there are file descriptors higher than the max open from before the limit dropped, that's not our problem - io::FD fd = io::FD::sysconf_SC_OPEN_MAX(); - while ((fd = fd.prev()) > io::FD::stderr()) - { - if (fd.close() == 0) - FPRINTF(stderr, "close fd %d\n"_fmt, fd.uncast_dammit()); - } - fd = io::FD::open("/dev/null"_s, O_RDWR); - if (fd == io::FD()) - { - perror("open /dev/null"); - exit(1); - } - fd.dup2(io::FD::stdin()); - fd.dup2(io::FD::stdout()); - fd.close(); - } - while (1) - { - // write stuff to stderr - timestamp_seconds_buffer timestamp; - stamp_time(timestamp); - - if (!pid_login) - { - pid_login = start_process(monitor_conf.login_server); - FPRINTF(stderr, "[%s] forked login server: %lu\n"_fmt, - timestamp, static_cast<unsigned long>(pid_login)); - } - if (!pid_char) - { - pid_char = start_process(monitor_conf.char_server); - FPRINTF(stderr, "[%s] forked char server: %lu\n"_fmt, - timestamp, static_cast<unsigned long>(pid_char)); - } - if (!pid_map) - { - pid_map = start_process(monitor_conf.map_server); - FPRINTF(stderr, "[%s] forked map server: %lu\n"_fmt, - timestamp, static_cast<unsigned long>(pid_map)); - } - pid_t dead = wait(nullptr); - if (dead == -1) - { - perror("Failed to wait for child"); - exit(1); - } - if (pid_login == dead) - pid_login = 0; - if (pid_char == dead) - pid_char = 0; - if (pid_map == dead) - pid_map = 0; - } -} |