* added possibility to disable handling of incoming opcodes by the core (they will still be handled if a script is assigned!)
* script command: switchopcodehandler,<opcode> true(on)/false(off) * added script events _onworldsessioncreate/delete * added new conf option: HideDisabledOpcodes=1/0 * added possibility to spoof worldpackets
This commit is contained in:
parent
c87f175ad6
commit
d295e30b3f
@ -35,6 +35,10 @@ showopcodes=3
|
||||
// 0 - No
|
||||
hidefreqopcodes=1
|
||||
|
||||
// Hide disabled (= unhandled, but known) opcodes?
|
||||
// 1 - Yes
|
||||
// 0 - No
|
||||
HideDisabledOpcodes=0
|
||||
|
||||
// the IP or hostname the realm server is running on
|
||||
realmlist=localhost
|
||||
|
||||
@ -94,3 +94,20 @@ SAY Forget it, ${@0}, you have only permission ${@1} but need ${@2} to run the s
|
||||
LOG Player '${@0}' (p:${@1}) wanted to execute '${@3}' (p:${@2})
|
||||
EMOTE 66 // say NO!
|
||||
|
||||
|
||||
|
||||
// ----==== INTERNAL/MISC ====----
|
||||
|
||||
#script=_onworldsessioncreate
|
||||
// no args. called when an instance of the WorldSession class is created
|
||||
|
||||
//- script content here
|
||||
|
||||
|
||||
#script=_onworldsessiondelete
|
||||
// no args. called when an instance of the WorldSession class is deleted
|
||||
|
||||
//- script content here
|
||||
|
||||
|
||||
|
||||
|
||||
@ -58,6 +58,9 @@ void DefScriptPackage::_InitDefScriptInterface(void)
|
||||
AddFunc("gui",&DefScriptPackage::SCGui);
|
||||
AddFunc("sendwho",&DefScriptPackage::SCSendWho);
|
||||
AddFunc("getobjectdist",&DefScriptPackage::SCGetObjectDistance);
|
||||
AddFunc("switchopcodehandler",&DefScriptPackage::SCSwitchOpcodeHandler);
|
||||
AddFunc("opcodedisabled",&DefScriptPackage::SCOpcodeDisabled);
|
||||
AddFunc("spoofworldpacket",&DefScriptPackage::SCSpoofWorldPacket);
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::SCshdn(CmdSet& Set)
|
||||
@ -278,16 +281,18 @@ DefReturnResult DefScriptPackage::SCcastspell(CmdSet& Set)
|
||||
return true;
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::SCqueryitem(CmdSet& Set){
|
||||
uint32 id = atoi(Set.defaultarg.c_str());
|
||||
if(!id)
|
||||
return false;
|
||||
|
||||
DefReturnResult DefScriptPackage::SCqueryitem(CmdSet& Set)
|
||||
{
|
||||
if(!(((PseuInstance*)parentMethod)->GetWSession()))
|
||||
{
|
||||
logerror("Invalid Script call: SCqueryitem: WorldSession not valid");
|
||||
DEF_RETURN_ERROR;
|
||||
}
|
||||
|
||||
uint32 id = atoi(Set.defaultarg.c_str());
|
||||
if(!id)
|
||||
return false;
|
||||
|
||||
((PseuInstance*)parentMethod)->GetWSession()->SendQueryItem(id,0);
|
||||
return true;
|
||||
}
|
||||
@ -295,9 +300,8 @@ DefReturnResult DefScriptPackage::SCqueryitem(CmdSet& Set){
|
||||
DefReturnResult DefScriptPackage::SCtarget(CmdSet& Set)
|
||||
{
|
||||
// TODO: special targets: _self _pet _nearest ...
|
||||
DefReturnResult r;
|
||||
|
||||
if(!(((PseuInstance*)parentMethod)->GetWSession()))
|
||||
WorldSession *ws = ((PseuInstance*)parentMethod)->GetWSession();
|
||||
if(!ws)
|
||||
{
|
||||
logerror("Invalid Script call: SCtarget: WorldSession not valid");
|
||||
DEF_RETURN_ERROR;
|
||||
@ -309,21 +313,30 @@ DefReturnResult DefScriptPackage::SCtarget(CmdSet& Set)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: search through all objects. for now only allow to target player
|
||||
uint64 guid = (((PseuInstance*)parentMethod)->GetWSession()->plrNameCache.GetGuid(Set.defaultarg));
|
||||
|
||||
if( guid && ((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetObj(guid) ) // object must be near
|
||||
std::string what = stringToLower(Set.arg[0]);
|
||||
uint64 guid = 0;
|
||||
if(what == "guid")
|
||||
{
|
||||
((PseuInstance*)parentMethod)->GetWSession()->SendSetSelection(guid); // will also set the target for myCharacter
|
||||
r.ret=toString(guid);
|
||||
guid = DefScriptTools::toUint64(Set.defaultarg);
|
||||
}
|
||||
else if(what.empty() || what == "player")
|
||||
{
|
||||
// TODO: search through all objects. for now only allow to target player
|
||||
guid = ws->plrNameCache.GetGuid(Set.defaultarg);
|
||||
}
|
||||
|
||||
Object *obj = ws->objmgr.GetObj(guid);
|
||||
if(obj && obj->IsUnit() || obj->IsCorpse()) // only units and corpses are targetable
|
||||
{
|
||||
ws->SendSetSelection(guid); // will also set the target for myCharacter
|
||||
return toString(guid);
|
||||
}
|
||||
else
|
||||
{
|
||||
logdetail("Target '%s' not found!",Set.defaultarg.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return r;
|
||||
return "";
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set)
|
||||
@ -899,10 +912,16 @@ DefReturnResult DefScriptPackage::SCSendWorldPacket(CmdSet &Set)
|
||||
ByteBuffer *bb = bytebuffers.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname));
|
||||
if(bb)
|
||||
{
|
||||
uint32 opcode = (uint32)DefScriptTools::toNumber(Set.arg[0]);
|
||||
if(opcode) // prevent sending CMSG_NULL_ACTION
|
||||
uint16 opc = (uint16)DefScriptTools::toUint64(Set.arg[0]);
|
||||
if(!opc)
|
||||
{
|
||||
WorldPacket wp(opcode, bb->size());
|
||||
opc = (uint16)GetOpcodeID(Set.arg[0].c_str());
|
||||
if(opc == uint16(-1))
|
||||
return false;
|
||||
}
|
||||
if(opc) // prevent sending CMSG_NULL_ACTION
|
||||
{
|
||||
WorldPacket wp(opc, bb->size());
|
||||
if(bb->size())
|
||||
wp.append(bb->contents(), bb->size());
|
||||
ws->SendWorldPacket(wp);
|
||||
@ -1064,6 +1083,84 @@ DefReturnResult DefScriptPackage::SCGetObjectDistance(CmdSet &Set)
|
||||
return "";
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::SCSwitchOpcodeHandler(CmdSet &Set)
|
||||
{
|
||||
WorldSession *ws = ((PseuInstance*)parentMethod)->GetWSession();
|
||||
if(!ws)
|
||||
{
|
||||
logerror("Invalid Script call: SCRemoveOpcodeHandler: WorldSession not valid");
|
||||
DEF_RETURN_ERROR;
|
||||
}
|
||||
uint16 opc = (uint16)DefScriptTools::toUint64(Set.arg[0]);
|
||||
bool switchon = DefScriptTools::isTrue(Set.defaultarg);
|
||||
if(!opc) // ok we cant turn off MSG_NULL_ACTION with this, but who needs it anyway...
|
||||
{
|
||||
opc = (uint16)GetOpcodeID(Set.arg[0].c_str());
|
||||
if(opc == uint16(-1))
|
||||
return false;
|
||||
}
|
||||
else if(opc >= MAX_OPCODE_ID)
|
||||
{
|
||||
logerror("Can't enable/disable opcode handling of %u", opc);
|
||||
return false;
|
||||
}
|
||||
if(switchon)
|
||||
ws->EnableOpcode(opc);
|
||||
else
|
||||
ws->DisableOpcode(opc);
|
||||
|
||||
logdebug("Opcode handler for %s (%u) %s",GetOpcodeName(opc), opc, switchon ? "enabled" : "disabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::SCOpcodeDisabled(CmdSet &Set)
|
||||
{
|
||||
WorldSession *ws = ((PseuInstance*)parentMethod)->GetWSession();
|
||||
if(!ws)
|
||||
{
|
||||
logerror("Invalid Script call: SCOpcodeDisabled: WorldSession not valid");
|
||||
DEF_RETURN_ERROR;
|
||||
}
|
||||
uint16 opc = (uint16)DefScriptTools::toUint64(Set.defaultarg);
|
||||
if(!opc)
|
||||
{
|
||||
opc = (uint16)GetOpcodeID(Set.arg[0].c_str());
|
||||
if(opc == uint16(-1))
|
||||
return false;
|
||||
}
|
||||
else if(opc >= MAX_OPCODE_ID)
|
||||
{
|
||||
logerror("SCOpcodeDisabled: Opcode %u out of range", opc);
|
||||
return false; // we can NEVER handle out of range opcode, but since its not disabled, return false
|
||||
}
|
||||
return ws->IsOpcodeDisabled(opc);
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::SCSpoofWorldPacket(CmdSet &Set)
|
||||
{
|
||||
WorldSession *ws = ((PseuInstance*)parentMethod)->GetWSession();
|
||||
if(!ws)
|
||||
{
|
||||
logerror("Invalid Script call: SCSpoofWorldPacket: WorldSession not valid");
|
||||
DEF_RETURN_ERROR;
|
||||
}
|
||||
ByteBuffer *bb = bytebuffers.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname));
|
||||
if(bb)
|
||||
{
|
||||
uint32 opcode = (uint32)DefScriptTools::toNumber(Set.arg[0]);
|
||||
if(opcode) // ok, here again CMSG_NULL_ACTION doesnt work, but who cares
|
||||
{
|
||||
WorldPacket *wp = new WorldPacket(opcode, bb->size()); // will be deleted by the opcode handler later
|
||||
if(bb->size())
|
||||
wp->append(bb->contents(), bb->size());
|
||||
logdebug("Spoofing WorldPacket with opcode %s (%u), size %u",GetOpcodeName(opcode),opcode,wp->size());
|
||||
ws->AddToPktQueue(wp); // handle this packet as if it was sent by the server
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DefScriptPackage::My_LoadUserPermissions(VarSet &vs)
|
||||
{
|
||||
static char *prefix = "USERS::";
|
||||
|
||||
@ -49,5 +49,8 @@ DefReturnResult SCBBPutPackedGuid(CmdSet&);
|
||||
DefReturnResult SCGui(CmdSet&);
|
||||
DefReturnResult SCSendWho(CmdSet&);
|
||||
DefReturnResult SCGetObjectDistance(CmdSet&);
|
||||
DefReturnResult SCSwitchOpcodeHandler(CmdSet&);
|
||||
DefReturnResult SCOpcodeDisabled(CmdSet&);
|
||||
DefReturnResult SCSpoofWorldPacket(CmdSet&);
|
||||
|
||||
#endif
|
||||
|
||||
@ -404,6 +404,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v)
|
||||
networksleeptime=atoi(v.Get("NETWORKSLEEPTIME").c_str());
|
||||
showopcodes=atoi(v.Get("SHOWOPCODES").c_str());
|
||||
hidefreqopcodes=(bool)atoi(v.Get("HIDEFREQOPCODES").c_str());
|
||||
hideDisabledOpcodes=(bool)atoi(v.Get("HIDEDISABLEDOPCODES").c_str());
|
||||
enablecli=(bool)atoi(v.Get("ENABLECLI").c_str());
|
||||
allowgamecmd=(bool)atoi(v.Get("ALLOWGAMECMD").c_str());
|
||||
enablechatai=(bool)atoi(v.Get("ENABLECHATAI").c_str());
|
||||
|
||||
@ -45,6 +45,7 @@ class PseuInstanceConf
|
||||
uint16 networksleeptime;
|
||||
uint8 showopcodes;
|
||||
bool hidefreqopcodes;
|
||||
bool hideDisabledOpcodes;
|
||||
bool allowgamecmd;
|
||||
bool enablecli;
|
||||
bool enablechatai;
|
||||
|
||||
@ -140,6 +140,7 @@ bool PlayerNameCache::ReadFromFile(void)
|
||||
}
|
||||
printf("\n");
|
||||
delete nameptr;
|
||||
fh.flush();
|
||||
fh.close();
|
||||
if(success)
|
||||
log("PlayerNameCache successfully loaded.");
|
||||
@ -409,6 +410,7 @@ void ItemProtoCache_WriteDataToCache(WorldSession *session)
|
||||
fh.write((char*)buf.contents(),buf.size());
|
||||
counter++;
|
||||
}
|
||||
fh.flush();
|
||||
fh.close();
|
||||
log("ItemProtoCache: Saved %u Item Prototypes",counter);
|
||||
}
|
||||
@ -523,6 +525,7 @@ void CreatureTemplateCache_WriteDataToCache(WorldSession *session)
|
||||
fh.write((char*)buf.contents(),buf.size());
|
||||
counter++;
|
||||
}
|
||||
fh.flush();
|
||||
fh.close();
|
||||
log("CreatureTemplateCache: Saved %u Creature Templates",counter);
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
#include "Auth/Sha1.h"
|
||||
#include "Auth/BigNumber.h"
|
||||
#include "Auth/AuthCrypt.h"
|
||||
#include "Opcodes.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSocket.h"
|
||||
#include "RealmSocket.h"
|
||||
@ -34,11 +33,16 @@ WorldSession::WorldSession(PseuInstance *in)
|
||||
_lag_ms = 0;
|
||||
//...
|
||||
|
||||
in->GetScripts()->RunScriptIfExists("_onworldsessioncreate");
|
||||
|
||||
DEBUG(logdebug("WorldSession 0x%X constructor finished",this));
|
||||
}
|
||||
|
||||
WorldSession::~WorldSession()
|
||||
{
|
||||
_instance->GetScripts()->RunScriptIfExists("_onworldsessiondelete");
|
||||
|
||||
logdebug("~WorldSession(): %u packets left unhandled, and %u delayed. deleting.",pktQueue.size(),delayedPktQueue.size());
|
||||
WorldPacket *packet;
|
||||
// clear the queue
|
||||
while(pktQueue.size())
|
||||
@ -46,6 +50,13 @@ WorldSession::~WorldSession()
|
||||
packet = pktQueue.next();
|
||||
delete packet;
|
||||
}
|
||||
// clear the delayed queue
|
||||
while(delayedPktQueue.size())
|
||||
{
|
||||
packet = delayedPktQueue.back().pkt;
|
||||
delayedPktQueue.c.pop_back();
|
||||
delete packet;
|
||||
}
|
||||
|
||||
if(_channels)
|
||||
delete _channels;
|
||||
@ -156,27 +167,30 @@ void WorldSession::HandleWorldPacket(WorldPacket *packet)
|
||||
}
|
||||
|
||||
bool hideOpcode = false;
|
||||
bool disabledOpcode = IsOpcodeDisabled(packet->GetOpcode());
|
||||
if(disabledOpcode && GetInstance()->GetConf()->hideDisabledOpcodes)
|
||||
hideOpcode = true;
|
||||
|
||||
// TODO: Maybe make table or something with all the frequently opcodes
|
||||
if (packet->GetOpcode() == SMSG_MONSTER_MOVE)
|
||||
if (GetInstance()->GetConf()->hidefreqopcodes)
|
||||
{
|
||||
hideOpcode = true;
|
||||
switch(packet->GetOpcode())
|
||||
{
|
||||
case SMSG_MONSTER_MOVE:
|
||||
hideOpcode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( (known && GetInstance()->GetConf()->showopcodes==1)
|
||||
|| ((!known) && GetInstance()->GetConf()->showopcodes==2)
|
||||
|| (GetInstance()->GetConf()->showopcodes==3) )
|
||||
{
|
||||
if(!(GetInstance()->GetConf()->hidefreqopcodes && hideOpcode))
|
||||
logcustom(1,YELLOW,">> Opcode %u [%s] (%s, %u bytes)", packet->GetOpcode(), GetOpcodeName(packet->GetOpcode()), known ? "Known" : "UNKNOWN", packet->size());
|
||||
if(!hideOpcode)
|
||||
logcustom(1,YELLOW,">> Opcode %u [%s] (%s, %u bytes)", packet->GetOpcode(), GetOpcodeName(packet->GetOpcode()), (known ? (disabledOpcode ? "Disabled" : "Known") : "UNKNOWN"), packet->size());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// call the opcode handler
|
||||
if(known)
|
||||
(this->*table[hpos].handler)(*packet);
|
||||
|
||||
// if there is a script attached to that opcode, call it now.
|
||||
// note: the pkt rpos needs to be reset by the scripts!
|
||||
std::string scname = "opcode::";
|
||||
@ -190,6 +204,12 @@ void WorldSession::HandleWorldPacket(WorldPacket *packet)
|
||||
GetInstance()->GetScripts()->bytebuffers.Unlink(pktname);
|
||||
}
|
||||
|
||||
// call the opcode handler
|
||||
if(known && !disabledOpcode)
|
||||
{
|
||||
packet->rpos(0);
|
||||
(this->*table[hpos].handler)(*packet);
|
||||
}
|
||||
}
|
||||
catch (ByteBufferException bbe)
|
||||
{
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define _WORLDSESSION_H
|
||||
|
||||
#include <queue>
|
||||
#include <bitset>
|
||||
|
||||
#include "common.h"
|
||||
#include "PseuWoW.h"
|
||||
@ -11,6 +12,7 @@
|
||||
#include "SharedDefines.h"
|
||||
#include "ObjMgr.h"
|
||||
#include "CacheHandler.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
class WorldSocket;
|
||||
class WorldPacket;
|
||||
@ -84,10 +86,16 @@ public:
|
||||
|
||||
void HandleWorldPacket(WorldPacket*);
|
||||
|
||||
inline void DisableOpcode(uint16 opcode) { _disabledOpcodes[opcode] = true; }
|
||||
inline void EnableOpcode(uint16 opcode) { _disabledOpcodes[opcode] = false; }
|
||||
inline bool IsOpcodeDisabled(uint16 opcode) { return _disabledOpcodes[opcode]; }
|
||||
|
||||
PlayerNameCache plrNameCache;
|
||||
ObjMgr objmgr;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
OpcodeHandler *_GetOpcodeHandlerTable(void) const;
|
||||
|
||||
// Helpers
|
||||
@ -148,6 +156,7 @@ private:
|
||||
World *_world;
|
||||
WhoList _whoList;
|
||||
uint32 _lag_ms;
|
||||
std::bitset<MAX_OPCODE_ID> _disabledOpcodes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user