general fixes before release [part 1].

* added script handler "_onchatmessage" that gets triggered when ANY chat message is recieved.
* TODO: finish & debug "processchatai" and "registerchataiscript" scripts.
This commit is contained in:
False.Genesis 2007-08-27 20:46:27 +00:00
parent 49338c6e6a
commit cb26f947c5
13 changed files with 446 additions and 60 deletions

View File

@ -0,0 +1,157 @@
// -------------------------------------------
#script=_onchatmessage
// purpose: do something if specific chat messages are recieved.
// args:
// @def: chat message text
// @0: message type id (check ChatMsg enum in src/Client/SharedDefines.h)
// @1: language id (also defined in SharedDefines.h), alternatively look up bin/data/scp/language.scp
// @2: GUID of the player or creature this msg came from
// @3: channel name. empty string if the chat message was not sent in a channel (for example say, yell or whisper)
//--------------------------------------------
// not using this yet, still more or less bugged. add stuff manually if you relly need.
// processchatai,{${@0}},{${@1}},{${@2}},{${@3}} ${@def}
// ----------------------------------
#script=processchatai
// ----------------------------------
// purpose: iterate over registered AI scripts, test if the chat message matches the condition,
// and execute appropriate script with predefined arguments
// TODO: get object name (player or creature) and pass it to the called scripts
// filter out chat messages that came from us
if ?{equal,${@myguid} ${@2}}
return false
endif
// filter out CHAT_MSG_WHISPER_INFORM ("whisper to ... : blah blah")
if ?{equal,${@0} 7}
logdebug -- chat is whisper inform, skipping
return false
endif
// split the msg into a list containing only words. remove special characters also.
lcsplit,wlist,{ !?,;.:-_\\/<>()[]"$=+&} ${@def}
logdebug JOIN: ?{ljoin,wlist +}
// remove empty entries
lclean,wlist
// obtain name of the language that was used
set,langname ?{GetSCPValue,lang,${@1} name}
default,langname UNK LANG
set,msg ?{lowercase ${@def}}
set,i 0
set,len ?{llen pattern_list}
loop
if ?{equal,${i} ${len}}
exitloop
endif
set,script ?{lindex,script_list ${i}}
set,cond ?{lindex,cond_list ${i}}
set,pattern ?{lindex,pattern_list ${i}}
set,call false
if ?{equal,NONE ${cond}}
set,call true
else
if ?{equal,ALL ${cond}}
set,call ?{lcontains_ext,{${pattern}},{ } ${msg}}
else
if ?{equal,EXACT ${cond}}
out ${pattern}
out ${msg}
set,call ?{equal,{${pattern}} ${msg}}
else
if ?{equal,EXACT_PARTIAL ${cond}}
set,call ?{strlen ?{strfind,{${pattern}} ${msg}}}
endif
endif
endif
endif
if ${call}
logdebug DEBUG: ChatAI: calling script ${script}, condition ${cond} matched.
${script},{${@0}},{${@1}},{${@2}},{${@3}},{${langname}} ${@def}
else
logdebug DEBUG: ChatAI: NOT called script ${script}, condition ${cond} not matched.
endif
add,i 1
endloop
// cleanup
ldelete wlist
return true
// ----------------------------------
#script=RegisterChatAIScript
// ----------------------------------
// purpose: registers a custom script to handle an incoming chat message if a condition is matched.
// args:
// @def: word pattern (words are delimited with spaces)
// @0: script name that has to be called if the condition is matched
// @1: condition. allowed values are:
// ALL - the chat message must contain all words provided
// ANY - the chat message must contain any word provided -- NOT WORKING YET [didnt find the reason yet :( ]--
// ALL_ORDER - same like all, but in the order provided -- NOT YET IMPLEMENTED
// ALL_CONSECUTIVE - same like ALL_ORDER, but the words must follow exactly one after another -- NOT YET IMPLEMENTED
// EXACT - the chat message must be exactly equal to the string supplied.
// EXACT_PARTIAL - the chat message must contain the string supplied.
// NONE - the script will be always called; no testing is done. its up to the user how to deal with it. (default)
// note that @def is not case sensitive!
if ?{not ?{strlen ${@0}}}
logerror Script error: RegisterChatAIScript: no function defined (called by '${@caller}')
return false
endif
set,pattern ?{lowercase ${@def}}
set,cond ?{uppercase ${@1}}
default,cond NONE
if ?{isset [${@0};${pattern};${cond}]}
logdebug Chat AI script already registered. script: '${@0}', condition: ${cond}, pattern: '${@def}'
return false
endif
if ?{strlen ?{strfind,ALL ${cond}}}
set,lname ${@0}_pattern
lcsplit,{${lname}},{ } ${pattern}
if ?{not ?{llen ${lname}}}
logerror Script error: RegisterChatAIScript: pattern is empty, but required! (called by '${@caller}')
return false
endif
lpushback,#processchatai::pattern_list ${lname}
else
lpushback,#processchatai::pattern_list ${pattern}
endif
lpushback,#processchatai::script_list ${@0}
lpushback,#processchatai::cond_list ${cond}
set,[${@0};${pattern};${cond}]
logdetail Chat AI script registered. script: '${@0}', condition: ${cond}, pattern: '${@def}' [now ?{llen #processchatai::pattern_list} registered]
return true

View File

@ -7,28 +7,97 @@
// @0: list name, @def: search string
set,i 0
set,l ?{globname ${@0}}
out list: ${l} - len: ?{llen ${l}}
set,l ?{globname,{${@caller}} ${@0}}
if ?{not ?{llen ${l}}}
return
return
endif
set,result false
loop
if ?{equal,${i} ?{llen ${l}}}
exitloop
endif
set,elem ?{lindex,{${l}} ${i}}
if ?{equal,{${elem}} ${@def}}
set,result true
exitloop
endif
add,i 1
if ?{equal,${i} ?{llen ${l}}}
exitloop
endif
set,elem ?{lindex,{${l}} ${i}}
if ?{equal,{${elem}} ${@def}}
set,result true
exitloop
endif
add,i 1
endloop
unset i
unset l
unset elem
return ${result}
// -----------------------------------------
#script=lcontains_ext
// -----------------------------------------
// return true if any substring in @def matches any element in list @0.
// default delimiter is space, override with @1.
// by default, any char in @1 serves as delimiter.
// if you set @2 to true, the exact string @1 is used as delimiter (no default is set)
// to check for individual chars in @def, use the following: "lcontains_ex,<list>,,true string_of_chars_for_example"
set,i 0
set,j 0
set,l ?{globname,{${@caller}} ${@0}}
set,delim ${@1}
if ${@2}
set,engine lsplit
else
set,engine lcsplit
// take care of the whitespaces: we use space as delimiter!
default,delim { }
endif
${engine},myl,{${delim}} ${@def}
// list to check must at least contain 1 element
if ?{not ?{llen ${l}}}
return
endif
// and our pattern list must contain 1 element also
if ?{not ?{llen myl}}
return
endif
set,result false
loop
if ?{equal,${i} ?{llen ${l}}}
exitloop
endif
set,elem ?{lindex,{${l}} ${i}}
set,j 0
loop
if ?{equal,${j} ?{llen myl}}
exitloop
endif
set,myelem ?{lindex,myl ${j}}
if ?{equal,{${elem}} ${myelem}}
set,result true
exitloop
endif
add,j 1
endloop
if ${result}
exitloop
endif
add,i 1
endloop
unset i
unset j
unset l
unset engine
unset elem
unset myelem
ldelete myl
unset delim
return ${result}

View File

@ -0,0 +1,32 @@
// example script that registers itself to get called on incoming chat messages.
// args passed to this script are as follows:
// @def: chat msg
// @0: message type
// @1: lang id
// @2: guid of sender
// @3: channel name
// @4: language name
#onload
// call us only if somebody says a text containing "hello" and "world"
RegisterChatAIScript,chat_ai_helloworld,EXACT hello world
#/onload
// ---------------------------------------
#script=chat_ai_helloworld
// ---------------------------------------
if ?{equal,${@0} 0}
// say some stuff is the language that was used by the sender
say,${@1} Hello World! This is an example!
else
// else shout back in our default language
if ?{equal,${@0} 5}
yell Yah "Hello World!" is widely used to proof that something is working!!
else
if ?{equal,${@0} 14}
chan,{${@3}} Recieved a nice "Hello World" in channel ${@3} ;)
endif
endif
endif

View File

@ -4,6 +4,7 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdarg.h>
#include "VarSet.h"
#include "DefScript.h"
#include "DefScriptTools.h"
@ -21,6 +22,9 @@ enum DefScriptBlockType
// --- SECTION FOR SCRIPT PACKAGES ---
DefScriptPackage::DefScriptPackage()
{
SetLog(printf);
SetDebugLog(printf);
SetErrorLog(printf);
_eventmgr=new DefScript_DynamicEventMgr(this);
_InitFunctions();
# ifdef USING_DEFSCRIPT_EXTENSIONS
@ -35,6 +39,30 @@ DefScriptPackage::~DefScriptPackage()
Clear();
}
void DefScriptPackage::Log(const char* fmt,...)
{
va_list ap;
va_start(ap, fmt);
(*_slog)(fmt,ap);
va_end(ap);
}
void DefScriptPackage::DebugLog(const char* fmt,...)
{
va_list ap;
va_start(ap, fmt);
(*_sdebuglog)(fmt,ap);
va_end(ap);
}
void DefScriptPackage::ErrorLog(const char* fmt,...)
{
va_list ap;
va_start(ap, fmt);
(*_serrorlog)(fmt,ap);
va_end(ap);
}
void DefScriptPackage::SetParentMethod(void *p)
{
parentMethod = p;
@ -89,6 +117,7 @@ void DefScriptPackage::_InitFunctions(void)
AddFunc("lowercase",&DefScriptPackage::func_lowercase);
AddFunc("random",&DefScriptPackage::func_random);
AddFunc("fileexists",&DefScriptPackage::func_fileexists);
AddFunc("strfind",&DefScriptPackage::func_strfind);
// list functions
AddFunc("lpushback",&DefScriptPackage::func_lpushback);
@ -243,7 +272,7 @@ bool DefScriptPackage::LoadScriptFromFile(std::string fn){
DeleteScript(curScript->GetName());
sn = stringToLower(value);
_UpdateOrCreateScriptByName(sn);
_DEFSC_DEBUG(printf("DefScript: now loading '%s'\n",sn.c_str()));
_DEFSC_DEBUG_LOG("DefScript: now loading '%s'\n",sn.c_str());
curScript=Script[sn];
}
else if(line=="debug")
@ -631,12 +660,12 @@ void DefScriptPackage::SplitLine(CmdSet& Set,std::string line){
// extract cmd+params and txt
for(i=0;i<line.length();i++){
if(line.at(i)=='{')
if(line[i]=='{')
bracketsOpen++;
if(line.at(i)=='}')
if(line[i]=='}')
bracketsOpen--;
if( line.at(i)==',' && !bracketsOpen)
if( line[i]==',' && !bracketsOpen)
{
if(!cmdDefined){
Set.cmd=tempLine;
@ -648,7 +677,7 @@ void DefScriptPackage::SplitLine(CmdSet& Set,std::string line){
tempLine.clear();
}
else if( line.at(i)==' ' && !bracketsOpen)
else if( line[i]==' ' && !bracketsOpen)
{
if(!cmdDefined){
Set.cmd=tempLine;
@ -657,15 +686,13 @@ void DefScriptPackage::SplitLine(CmdSet& Set,std::string line){
Set.arg[curParam]=tempLine;
}
Set.defaultarg=line.substr(i,line.length()-i);
Set.defaultarg.erase(0,1);
//tempLine.clear();
Set.defaultarg=line.substr(i+1,line.length()-i);
break;
}
else
{
tempLine+=line.at(i);
tempLine+=line[i];
}
}
@ -916,6 +943,18 @@ std::string DefScriptPackage::_NormalizeVarName(std::string vn_in, std::string s
DefReturnResult DefScriptPackage::Interpret(CmdSet& Set)
{
// TODO: remove this debug block again as soon as the interpreter bugs are fixed.
# ifdef DEF_DEBUG_SCRIPT_CALLS
printf("DefScriptPackage::Interpret(), pSet=0x%X\n",&Set);
printf("cmd = '%s'\n",Set.cmd.c_str());
unsigned int ctr=0;
for(_CmdSetArgMap::iterator i=Set.arg.begin(); i!=Set.arg.end(); i++)
{
printf("arg[%u] = '%s'\n",ctr++,i->second.c_str());
}
printf("defaultarg = '%s'\n",Set.defaultarg.c_str());
# endif
DefReturnResult result;
// first search if the script is defined in the internal functions
@ -952,3 +991,19 @@ void DefScriptPackage::_UpdateOrCreateScriptByName(std::string sn)
newscript->SetName(sn); // necessary that the script knows its own name
Script[sn] = newscript;
}
// TODO: add support for safe brackets ( "\{" , "\}" ) and fix the string this way
std::string DefScriptPackage::SecureString(std::string s)
{
std::string out;
for(unsigned int i = 0; i < s.length(); i++)
{
if(s[i] == '{')
out += '[';
else if(s[i] == '}')
out += ']';
else
out += s[i];
}
return out;
}

View File

@ -13,6 +13,8 @@
class DefScriptPackage;
class DefScript;
typedef void (*_slog_func)(const char*,...);
// general struct for if..else..endif / loop..endloop blocks
struct Def_Block
{
@ -124,6 +126,17 @@ public:
bool HasFunc(std::string);
void DelFunc(std::string);
ListStorage lists;
std::string SecureString(std::string s);
// own logging functions. default is printf.
// DO NOT USE THEM YET! THEY DO NOT WORK CORRECTLY!
// need some help with this [FG]
inline void SetLog(void *ptr) { _slog=(_slog_func)ptr; }
inline void SetDebugLog(void *ptr) { _sdebuglog=(_slog_func)ptr; }
inline void SetErrorLog(void *ptr) { _serrorlog=(_slog_func)ptr; }
void Log(const char*,...);
void DebugLog(const char*,...);
void ErrorLog(const char*,...);
std::string scPath;
@ -146,6 +159,7 @@ private:
std::map<std::string,DefScript*> Script;
std::map<std::string,unsigned char> scriptPermissionMap;
DefScriptFunctionTable _functable;
_slog_func _slog,_serrorlog,_sdebuglog;
// Usable internal basic functions:
DefReturnResult func_default(CmdSet&);
@ -185,6 +199,7 @@ private:
DefReturnResult func_lowercase(CmdSet&);
DefReturnResult func_random(CmdSet&);
DefReturnResult func_fileexists(CmdSet&);
DefReturnResult func_strfind(CmdSet&);
// list functions
DefReturnResult func_lpushback(CmdSet&);

View File

@ -1,10 +1,15 @@
#ifndef DEFSCRIPTDEFINES_H
#define DEFSCRIPTDEFINES_H
// use this directive to check if the parser is working correctly
#define DEF_DEBUG_SCRIPT_CALLS
#ifdef _DEBUG
# define _DEFSC_DEBUG(code) code;
# define _DEFSC_DEBUG_LOG DebugLog // does NOT YET work!!
#else
# define _DEFSC_DEBUG(code)
# define _DEFSC_DEBUG_LOG
#endif
#if COMPILER == COMPILER_MICROSOFT

View File

@ -344,13 +344,17 @@ DefReturnResult DefScriptPackage::func_strlen(CmdSet& Set)
DefReturnResult DefScriptPackage::func_equal(CmdSet& Set)
{
bool result;
if(stringToLower(Set.arg[1])=="ignore")
{
return stringToLower(Set.defaultarg)==stringToLower(Set.arg[0]);
result=stringToLower(Set.defaultarg)==stringToLower(Set.arg[0]);
}
return Set.defaultarg==Set.arg[0];
result=Set.defaultarg==Set.arg[0];
_DEFSC_DEBUG(printf("DEFSCRIPT: func_equal: ['%s'=='%s'] = %s\n",Set.arg[0].c_str(),Set.defaultarg.c_str(),result?"true":"false"));
return result;
}
DefReturnResult DefScriptPackage::func_smaller(CmdSet& Set)
{
return toNumber(Set.arg[0]) < toNumber(Set.defaultarg);
@ -468,5 +472,13 @@ DefReturnResult DefScriptPackage::func_fileexists(CmdSet& Set)
return false;
}
DefReturnResult DefScriptPackage::func_strfind(CmdSet& Set)
{
unsigned int pos = Set.defaultarg.find(Set.arg[0],(unsigned int)toNumber(Set.arg[1]));
if(pos == std::string::npos)
return "";
return toString((uint64)pos);
}

View File

@ -174,20 +174,22 @@ DefReturnResult DefScriptPackage::func_lindex(CmdSet& Set)
}
// clean list: remove every element that matches @def
// use this function only to remove empty straings from a list
// use _only_ this function to remove empty strings from a list
DefReturnResult DefScriptPackage::func_lclean(CmdSet& Set)
{
unsigned int r=0;
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname));
if(!l)
return "";
for(DefList::iterator i=l->begin(); i!=l->end(); i++)
for(DefList::iterator i=l->begin(); i!=l->end(); )
{
if(*i == Set.defaultarg)
{
l->erase(i);
i = l->erase(i);
r++;
continue;
}
i++;
}
return toString((uint64)r);
}

View File

@ -44,6 +44,7 @@ void DefScriptPackage::_InitDefScriptInterface(void)
AddFunc("getplayerperm",&DefScriptPackage::SCGetPlayerPerm);
AddFunc("getscriptperm",&DefScriptPackage::SCGetScriptPerm);
AddFunc("lgetfiles",&DefScriptPackage::SCGetFileList);
AddFunc("printscript",&DefScriptPackage::SCPrintScript);
}
DefReturnResult DefScriptPackage::SCshdn(CmdSet& Set)
@ -756,6 +757,17 @@ DefReturnResult DefScriptPackage::SCGetFileList(CmdSet& Set)
return toString((uint64)l->size());
}
DefReturnResult DefScriptPackage::SCPrintScript(CmdSet &Set)
{
DefScript *sc = GetScript(DefScriptTools::stringToLower(Set.defaultarg));
for(uint32 i = 0; i < sc->GetLines(); i++)
{
logcustom(0,GREEN,sc->GetLine(i).c_str());
}
return "";
}
void DefScriptPackage::My_LoadUserPermissions(VarSet &vs)

View File

@ -36,5 +36,6 @@ DefReturnResult SCObjectKnown(CmdSet&);
DefReturnResult SCGetPlayerPerm(CmdSet&);
DefReturnResult SCGetScriptPerm(CmdSet&);
DefReturnResult SCGetFileList(CmdSet&);
DefReturnResult SCPrintScript(CmdSet &Set);
#endif

View File

@ -92,7 +92,8 @@ PseuInstance::~PseuInstance()
log_close();
}
bool PseuInstance::Init(void) {
bool PseuInstance::Init(void)
{
log_prepare("logfile.txt",this);
log("");
log("--- Initializing Instance ---");
@ -105,11 +106,14 @@ bool PseuInstance::Init(void) {
srand((unsigned)time(NULL));
RAND_set_rand_method(RAND_SSLeay()); // init openssl randomizer
_scp=new DefScriptPackage();
_scp=new DefScriptPackage();
_scp->SetParentMethod((void*)this);
_conf=new PseuInstanceConf();
_conf=new PseuInstanceConf();
_scp->SetPath(_scpdir);
_scp->SetLog(logdetail); // does anyone have an idea why log() is not accepted here?
_scp->SetDebugLog(logdebug);
_scp->SetErrorLog(logerror);
_scp->variables.Set("@version_short",_ver_short);
_scp->variables.Set("@version",_ver);

View File

@ -204,6 +204,7 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const
{MSG_MOVE_HEARTBEAT, &WorldSession::_HandleMovementOpcode},
{MSG_MOVE_FALL_LAND, &WorldSession::_HandleMovementOpcode},
{MSG_MOVE_TELEPORT_ACK, &WorldSession::_HandleTelePortAckOpcode},
{SMSG_COMPRESSED_UPDATE_OBJECT, &WorldSession::_HandleCompressedUpdateObjectOpcode},
{SMSG_UPDATE_OBJECT, &WorldSession::_HandleUpdateObjectOpcode},
{SMSG_CAST_RESULT, &WorldSession::_HandleCastResultOpcode},
@ -368,16 +369,17 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
}
bool char_found=false;
for(unsigned int i=0;i<num;i++){
logcustom(0,LGREEN,"## %s (%u) [%s/%s] Map: %s; Area: %s",
plr[i]._name.c_str(),
plr[i]._level,
GetDBMgr().GetRaceName(plr[i]._race).c_str(),
GetDBMgr().GetClassName_(plr[i]._class).c_str(),
GetDBMgr().GetMapName(plr[i]._mapId).c_str(),
GetDBMgr().GetAreaName(plr[i]._zoneId).c_str());
logdetail("-> coords: map=%u zone=%u x=%f y=%f z=%f",
plr[i]._mapId,plr[i]._zoneId,plr[i]._x,plr[i]._y,plr[i]._z);
for(unsigned int i=0;i<num;i++)
{
logcustom(0,LGREEN,"## %s (%u) [%s/%s] Map: %s; Area: %s",
plr[i]._name.c_str(),
plr[i]._level,
GetDBMgr().GetRaceName(plr[i]._race).c_str(),
GetDBMgr().GetClassName_(plr[i]._class).c_str(),
GetDBMgr().GetMapName(plr[i]._mapId).c_str(),
GetDBMgr().GetAreaName(plr[i]._zoneId).c_str());
logdetail("-> coords: map=%u zone=%u x=%f y=%f z=%f",
plr[i]._mapId,plr[i]._zoneId,plr[i]._x,plr[i]._y,plr[i]._z);
for(unsigned int inv=0;inv<20;inv++)
{
if(plr[i]._items[inv].displayId)
@ -385,32 +387,36 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
}
if(plr[i]._name==GetInstance()->GetConf()->charname)
{
char_found=true;
_myGUID=plr[i]._guid;
char_found=true;
_myGUID=plr[i]._guid;
GetInstance()->GetScripts()->variables.Set("@myguid",toString(plr[i]._guid));
GetInstance()->GetScripts()->variables.Set("@myrace",toString(plr[i]._race));
}
}
}
if(!char_found){
logerror("Character \"%s\" was not found on char list!",GetInstance()->GetConf()->charname.c_str());
GetInstance()->SetError();
return;
} else {
log("Entering World with Character \"%s\"...",GetInstance()->GetConf()->charname.c_str());
if(!char_found)
{
logerror("Character \"%s\" was not found on char list!",GetInstance()->GetConf()->charname.c_str());
GetInstance()->SetError();
return;
}
else
{
log("Entering World with Character \"%s\"...",GetInstance()->GetConf()->charname.c_str());
// create the character and add it to the objmgr.
// note: this is the only object that has to stay in memory unless its explicitly deleted by the server!
// that means even if the server sends create object with that guid, do NOT recreate it!!
MyCharacter *my = new MyCharacter();
my->Create(_myGUID);
objmgr.Add(my);
// create the character and add it to the objmgr.
// note: this is the only object that has to stay in memory unless its explicitly deleted by the server!
// that means even if the server sends create object with that guid, do NOT recreate it!!
MyCharacter *my = new MyCharacter();
my->Create(_myGUID);
objmgr.Add(my);
// TODO: initialize the world here, and load required maps.
// must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!!
// TODO: initialize the world here, and load required maps.
// must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!!
WorldPacket pkt(CMSG_PLAYER_LOGIN,8);
pkt << _myGUID;
SendWorldPacket(pkt);
WorldPacket pkt(CMSG_PLAYER_LOGIN,8);
pkt << _myGUID;
SendWorldPacket(pkt);
}
}
@ -537,6 +543,21 @@ void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket)
}
}
// temporaray implementation of custom script to handle recieved chat messages
// TODO: needs to be replaced later by script hooks
// TODO: also _onwhisper must be replaced by this!
if(!isCmd && GetInstance()->GetScripts()->GetScript("_onchatmessage"))
{
DEBUG(logdebug("DefScript chat handler found, executing _onchatmessage"));
CmdSet Set;
Set.arg[0] = toString(type);
Set.arg[1] = toString(lang);
Set.arg[2] = toString(target_guid);
Set.arg[3] = channel;
Set.defaultarg = GetInstance()->GetScripts()->SecureString(msg);
GetInstance()->GetScripts()->RunScript("_onchatmessage",&Set);
}
if(isCmd)
{
GetInstance()->GetScripts()->variables.Set("@thiscmd_name",plrname);

View File

@ -94,6 +94,7 @@ private:
void _HandleMotdOpcode(WorldPacket& recvPacket);
void _HandleNotificationOpcode(WorldPacket& recvPacket);
// helper functions to keep SMSG_(COMPRESSED_)UPDATE_OBJECT easy to handle
void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode
void _ValuesUpdate(uint64 uguid, WorldPacket& recvPacket); // ...
void _QueryObjectInfo(uint64 guid);