diff --git a/zone/QuestParserCollection.cpp b/zone/QuestParserCollection.cpp index d11f8c988..efa9985a5 100644 --- a/zone/QuestParserCollection.cpp +++ b/zone/QuestParserCollection.cpp @@ -29,6 +29,7 @@ #include extern Zone* zone; +extern void MapOpcodes(); QuestParserCollection::QuestParserCollection() { _player_quest_status = QuestUnloaded; @@ -66,6 +67,7 @@ void QuestParserCollection::ReloadQuests(bool reset_timers) { quest_manager.ClearAllTimers(); } + MapOpcodes(); _npc_quest_status.clear(); _player_quest_status = QuestUnloaded; _global_player_quest_status = QuestUnloaded; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 08fb6c97f..dbc57aa5d 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -388,6 +388,17 @@ void MapOpcodes() { ConnectedOpcodes[OP_OpenContainer] = &Client::Handle_OP_OpenContainer; } +void ClearMappedOpcode(EmuOpcode op) { + if(op >= _maxEmuOpcode) + return; + + ConnectedOpcodes[op] = nullptr; + auto iter = ConnectingOpcodes.find(op); + if(iter != ConnectingOpcodes.end()) { + ConnectingOpcodes.erase(iter); + } +} + int Client::HandlePacket(const EQApplicationPacket *app) { _ZP(Client_HandlePacket); @@ -420,10 +431,14 @@ int Client::HandlePacket(const EQApplicationPacket *app) switch(client_state) { case CLIENT_CONNECTING: { if(ConnectingOpcodes.count(opcode) != 1) { -//TODO: replace this 0 with the EQ opcode - LogFile->write(EQEMuLog::Error, "HandlePacket() Opcode error: Unexpected packet during CLIENT_CONNECTING: opcode: %s (#%d eq=0x%04x), size: %i", OpcodeNames[opcode], opcode, 0, app->size); -#if EQDEBUG >= 9 - std::cout << "Unexpected packet during CLIENT_CONNECTING: OpCode: 0x" << hex << setw(4) << setfill('0') << opcode << dec << ", size: " << app->size << std::endl; + //Hate const cast but everything in lua needs to be non-const even if i make it non-mutable + std::vector args; + args.push_back(const_cast(app)); + parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 1, &args); + +#if EQDEBUG >= 10 + LogFile->write(EQEMuLog::Error, "HandlePacket() Opcode error: Unexpected packet during CLIENT_CONNECTING: opcode:" + " %s (#%d eq=0x%04x), size: %i", OpcodeNames[opcode], opcode, 0, app->size); DumpPacket(app); #endif break; @@ -446,11 +461,16 @@ int Client::HandlePacket(const EQApplicationPacket *app) ClientPacketProc p; p = ConnectedOpcodes[opcode]; if(p == nullptr) { -#if (EQDEBUG>=5) + std::vector args; + args.push_back(const_cast(app)); + parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 0, &args); + +#if (EQDEBUG >= 10) char buffer[64]; app->build_header_dump(buffer); mlog(CLIENT__NET_ERR, "Unhandled incoming opcode: %s", buffer); - if(app->size<1000) + + if(app->size < 1000) DumpPacket(app->pBuffer, app->size); else{ std::cout << "Dump limited to 1000 characters:\n"; @@ -476,28 +496,6 @@ int Client::HandlePacket(const EQApplicationPacket *app) return(true); } - - -/*void Client::Handle_Connect_OP_SetDataRate(const EQApplicationPacket *app) -{ - // Set client datarate - //if (app->size != sizeof(float)) { - //LogFile->write(EQEMuLog::Error,"Wrong size on OP_SetDatarate. Got: %i, Expected: %i", app->size, sizeof(float)); - //return; - //} - //LogFile->write(EQEMuLog::Debug, "HandlePacket() OP_SetDataRate request : %f", *(float*) app->pBuffer); - //float tmpDR = *(float*) app->pBuffer; - //if (tmpDR <= 0.0f) { - //LogFile->write(EQEMuLog::Error,"HandlePacket() OP_SetDataRate INVALID request : %f <= 0", tmpDR); - //LogFile->write(EQEMuLog::Normal,"WARNING: Setting datarate for client to 5.0 expect a client lock up =("); - //tmpDR = 5.0f; - //} - //if (tmpDR > 25.0f) - //tmpDR = 25.0f; - //eqs->SetDataRate(tmpDR); - return; -}*/ - void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) { if(app->size != sizeof(ClientZoneEntry_Struct)) diff --git a/zone/embparser.cpp b/zone/embparser.cpp index c04834788..3a29e9cc3 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -111,7 +111,8 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_ENTER_AREA", "EVENT_LEAVE_AREA", "EVENT_RESPAWN", - "EVENT_DEATH_COMPLETE" + "EVENT_DEATH_COMPLETE", + "EVENT_UNHANDLED_OPCODE" }; PerlembParser::PerlembParser() : perl(nullptr) { diff --git a/zone/event_codes.h b/zone/event_codes.h index be332ca50..f78cdfd82 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -80,6 +80,7 @@ typedef enum { EVENT_LEAVE_AREA, EVENT_RESPAWN, EVENT_DEATH_COMPLETE, + EVENT_UNHANDLED_OPCODE, _LargestEventID } QuestEventID; diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index af33a34bc..e5cfbb72c 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -31,6 +31,8 @@ struct lua_registered_event { }; extern std::map> lua_encounter_events_registered; +extern void MapOpcodes(); +extern void ClearMappedOpcode(EmuOpcode op); void load_encounter(std::string name) { parse->EventEncounter(EVENT_ENCOUNTER_LOAD, name, 0); @@ -1009,6 +1011,14 @@ Lua_ItemInst lua_get_quest_item() { return quest_manager.GetQuestItem(); } +void lua_map_opcodes() { + MapOpcodes(); +} + +void lua_clear_opcode(int op) { + ClearMappedOpcode(static_cast(op)); +} + luabind::scope lua_register_general() { return luabind::namespace_("eq") [ @@ -1168,7 +1178,9 @@ luabind::scope lua_register_general() { luabind::def("stop_follow", &lua_stop_follow), luabind::def("get_initiator", &lua_get_initiator), luabind::def("get_owner", &lua_get_owner), - luabind::def("get_quest_item", &lua_get_quest_item) + luabind::def("get_quest_item", &lua_get_quest_item), + luabind::def("map_opcodes", &lua_map_opcodes), + luabind::def("clear_opcode", &lua_clear_opcode) ]; } @@ -1247,7 +1259,8 @@ luabind::scope lua_register_events() { luabind::value("augment_remove", static_cast(EVENT_AUGMENT_REMOVE)), luabind::value("enter_area", static_cast(EVENT_ENTER_AREA)), luabind::value("leave_area", static_cast(EVENT_LEAVE_AREA)), - luabind::value("death_complete", static_cast(EVENT_DEATH_COMPLETE)) + luabind::value("death_complete", static_cast(EVENT_DEATH_COMPLETE)), + luabind::value("unhandled_opcode", static_cast(EVENT_UNHANDLED_OPCODE)) ]; } diff --git a/zone/lua_packet.cpp b/zone/lua_packet.cpp index 761a2c26b..ea761b9b2 100644 --- a/zone/lua_packet.cpp +++ b/zone/lua_packet.cpp @@ -43,6 +43,11 @@ Lua_Packet::Lua_Packet(const Lua_Packet& o) { } } +int Lua_Packet::GetSize() { + Lua_Safe_Call_Int(); + return static_cast(self->size); +} + int Lua_Packet::GetOpcode() { Lua_Safe_Call_Int(); return static_cast(self->GetOpcode()); @@ -241,6 +246,7 @@ luabind::scope lua_register_packet() { .def(luabind::constructor()) .property("null", &Lua_Packet::Null) .property("valid", &Lua_Packet::Valid) + .def("GetSize", &Lua_Packet::GetSize) .def("GetOpcode", &Lua_Packet::GetOpcode) .def("SetOpcode", &Lua_Packet::SetOpcode) .def("WriteInt8", &Lua_Packet::WriteInt8) diff --git a/zone/lua_packet.h b/zone/lua_packet.h index 149d8a30e..c036594d1 100644 --- a/zone/lua_packet.h +++ b/zone/lua_packet.h @@ -25,6 +25,7 @@ public: Lua_Packet(const Lua_Packet& o); virtual ~Lua_Packet() { if(owned_) { EQApplicationPacket *ptr = GetLuaPtrData(); if(ptr) { delete ptr; } } } + int GetSize(); int GetOpcode(); void SetOpcode(int op); void WriteInt8(int offset, int value); diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index e042a753d..c3cb841af 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -113,7 +113,8 @@ const char *LuaEvents[_LargestEventID] = { "event_enter_area", "event_leave_area", "event_respawn", - "event_death_complete" + "event_death_complete", + "event_unhandled_opcode" }; extern Zone *zone; @@ -190,6 +191,7 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_ENTER_AREA] = handle_player_area; PlayerArgumentDispatch[EVENT_LEAVE_AREA] = handle_player_area; PlayerArgumentDispatch[EVENT_RESPAWN] = handle_player_respawn; + PlayerArgumentDispatch[EVENT_UNHANDLED_OPCODE] = handle_player_packet; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index f1ae37d16..c46107844 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -21,6 +21,7 @@ #include "lua_corpse.h" #include "lua_door.h" #include "lua_object.h" +#include "lua_packet.h" #include "zone.h" #include "lua_parser_events.h" @@ -472,6 +473,17 @@ void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, lua_setfield(L, -2, "resurrect"); } +void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, + std::vector *extra_pointers) { + Lua_Packet l_packet(reinterpret_cast(extra_pointers->at(0))); + luabind::object l_packet_o = luabind::object(L, l_packet); + l_packet_o.push(L); + lua_setfield(L, -2, "packet"); + + lua_pushboolean(L, extra_data == 1 ? true : false); + lua_setfield(L, -2, "connecting"); +} + void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector *extra_pointers) { } diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index d2c39aedd..8272e30c3 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -88,6 +88,8 @@ void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std std::vector *extra_pointers); void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector *extra_pointers); +void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, + std::vector *extra_pointers); void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector *extra_pointers);