* implemented usage of if/loop statements in #onload blocks

* check for if/loop/endif/endloop match in scripts
* check for brackets match (same amount of opening/closing brackets) at line load. skip corrupt lines
* some code cleanups
This commit is contained in:
False.Genesis 2007-03-23 21:00:20 +00:00
parent 74ded46daa
commit 0aaf7b45d6
11 changed files with 138 additions and 60 deletions

View File

@ -35,9 +35,6 @@ void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
if (!_initialized) return; if (!_initialized) return;
if (len < CRYPTED_RECV_LEN) return; if (len < CRYPTED_RECV_LEN) return;
_recv_i2=_recv_i;
_recv_j2=_recv_j;
for (size_t t = 0; t < CRYPTED_RECV_LEN; t++) for (size_t t = 0; t < CRYPTED_RECV_LEN; t++)
{ {
_recv_i %= _key.size(); _recv_i %= _key.size();
@ -70,13 +67,6 @@ void AuthCrypt::SetKey(uint8 *key, size_t len)
std::copy(key, key + len, _key.begin()); std::copy(key, key + len, _key.begin());
} }
void AuthCrypt::DecryptRescue(void)
{
// undos the last decrypt operation
_recv_i=_recv_i2;
_recv_j=_recv_j2;
}
AuthCrypt::~AuthCrypt() AuthCrypt::~AuthCrypt()
{ {
} }

View File

@ -40,12 +40,9 @@ class AuthCrypt
bool IsInitialized() { return _initialized; } bool IsInitialized() { return _initialized; }
void DecryptRescue(void);
private: private:
std::vector<uint8> _key; std::vector<uint8> _key;
uint8 _send_i, _send_j, _recv_i, _recv_j; uint8 _send_i, _send_j, _recv_i, _recv_j;
uint8 _send_i2, _send_j2, _recv_i2, _recv_j2;
bool _initialized; bool _initialized;
}; };
#endif #endif

View File

@ -10,6 +10,8 @@
using namespace DefScriptTools; using namespace DefScriptTools;
#define SN_ONLOAD "?onload?"
enum DefScriptBlockType enum DefScriptBlockType
{ {
BLOCK_IF, BLOCK_IF,
@ -136,13 +138,18 @@ bool DefScriptPackage::ScriptExists(std::string name)
for (std::map<std::string,DefScript*>::iterator i = Script.begin();i != Script.end();i++) for (std::map<std::string,DefScript*>::iterator i = Script.begin();i != Script.end();i++)
if(i->first == name && i->second != NULL) if(i->first == name && i->second != NULL)
return true; return true;
// actually, this part can lead to bugs, need to fix if it gets unstable
//for(unsigned int i=0;i<_functable.size();i++)
// if(name == _functable[i].name)
// return true;
return false; return false;
} }
void DefScriptPackage::DeleteScript(std::string sn)
{
if(ScriptExists(sn))
{
delete GetScript(sn);
Script.erase(sn);
}
}
bool DefScriptPackage::LoadByName(std::string name){ bool DefScriptPackage::LoadByName(std::string name){
return LoadScriptFromFile((scPath+name).append(".def"),name); return LoadScriptFromFile((scPath+name).append(".def"),name);
} }
@ -152,18 +159,21 @@ bool DefScriptPackage::LoadScriptFromFile(std::string fn, std::string sn){
std::string label, value, line; std::string label, value, line;
std::fstream f; std::fstream f;
bool load_debug=false,load_notify=false, exec=false; bool load_debug=false,load_notify=false, exec=false, cantload=false;
char z; char z;
f.open(fn.c_str(),std::ios_base::in); f.open(fn.c_str(),std::ios_base::in);
if(!f.is_open()) if(!f.is_open())
return false; return false;
std::deque<unsigned int> Blocks;
if(GetScript(sn)) if(GetScript(sn))
delete GetScript(sn); delete GetScript(sn);
DefScript *newscript = new DefScript(this); DefScript *newscript = new DefScript(this);
Script[sn] = newscript; Script[sn] = newscript;
Script[sn]->SetName(sn); // necessary that the script knows its own name Script[sn]->SetName(sn); // necessary that the script knows its own name
DeleteScript(SN_ONLOAD);
while(!f.eof()){ while(!f.eof()){
line.clear(); line.clear();
while (true) { while (true) {
@ -205,24 +215,92 @@ bool DefScriptPackage::LoadScriptFromFile(std::string fn, std::string sn){
} }
// help with loading lines where a space or tab have accidently been put after the cmd // help with loading lines where a space or tab have accidently been put after the cmd
if(memcmp(line.c_str(),"else ",5)==0 || memcmp(line.c_str(),"else\t",5)==0) line="else"; if(memcmp(line.c_str(),"else ",5)==0 || memcmp(line.c_str(),"else\t",5)==0) line="else";
if(memcmp(line.c_str(),"endif ",6)==0 || memcmp(line.c_str(),"endif\t",5)==0) line="endif"; else if(memcmp(line.c_str(),"endif ",6)==0 || memcmp(line.c_str(),"endif\t",5)==0) line="endif";
if(memcmp(line.c_str(),"loop ",5)==0 || memcmp(line.c_str(),"loop\t",5)==0) line="loop"; else if(memcmp(line.c_str(),"loop ",5)==0 || memcmp(line.c_str(),"loop\t",5)==0) line="loop";
if(memcmp(line.c_str(),"endloop ",8)==0 || memcmp(line.c_str(),"endloop\t",8)==0) line="endloop"; else if(memcmp(line.c_str(),"endloop ",8)==0 || memcmp(line.c_str(),"endloop\t",8)==0) line="endloop";
if(line=="else" || line=="endif" || line=="loop" || line=="endloop") if(line=="else" || line=="endif" || line=="loop" || line=="endloop")
line=stringToLower(line); line=stringToLower(line);
// check for correct block match
if(memcmp(line.c_str(),"if ",3)==0)
Blocks.push_back(BLOCK_IF);
else if(line=="else")
{
if(Blocks.empty() || Blocks.back()!=BLOCK_IF)
{
cantload=true;
break;
}
}
else if(line=="endif")
{
if(Blocks.empty() || Blocks.back()!=BLOCK_IF)
{
cantload=true;
break;
}
Blocks.pop_back();
}
else if(line=="loop")
Blocks.push_back(BLOCK_LOOP);
else if(line=="endloop")
{
if(Blocks.empty() || Blocks.back()!=BLOCK_LOOP)
{
cantload=true;
break;
}
Blocks.pop_back();
}
// check for correct bracket match
unsigned int bopen=0;
bool mismatch=false;
for(unsigned int bpos=0;bpos<line.length();bpos++)
{
if(line[bpos]=='{')
bopen++;
if(line[bpos]=='}')
{
if(bpos)
bopen--;
else
{
mismatch=true;
break;
}
}
}
if(mismatch || bopen) // no bracket must be left open now
{
printf("DefScript: Bracket mismatch at line '%s'\n",line.c_str());
continue; // continue with next line without adding the current line to script
}
if(load_debug) if(load_debug)
std::cout<<"~LOAD: "<<line<<"\n"; std::cout<<"~LOAD: "<<line<<"\n";
if(!exec) if(!exec)
Script[sn]->AddLine(line); Script[sn]->AddLine(line);
else else
{ {
this->RunSingleLineFromScript(line,Script[sn]); if(!ScriptExists(SN_ONLOAD))
Script[SN_ONLOAD] = new DefScript(this);
Script[SN_ONLOAD]->AddLine(line);
} }
} }
f.close(); f.close();
if(cantload)
{
printf("DefScript: Error loading script '%s'\n",sn.c_str());
DeleteScript(sn);
return false;
}
if(ScriptExists(SN_ONLOAD))
{
RunScript(SN_ONLOAD,NULL,sn);
DeleteScript(SN_ONLOAD);
}
if(load_notify) if(load_notify)
std::cout << "+> Script '" << sn << "' [" << fn << "] successfully loaded.\n"; std::cout << "+> Script '" << sn << "' [" << fn << "] successfully loaded.\n";
@ -320,7 +398,7 @@ bool DefScriptPackage::BoolRunScript(std::string name, CmdSet *pSet)
} }
// the referred pSet is the parent from which RunScript() has been called // the referred pSet is the parent from which RunScript() has been called
DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet) DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet,std::string override_name)
{ {
DefReturnResult r; DefReturnResult r;
if( (!ScriptExists(name)) && (!HasFunc(name)) ) if( (!ScriptExists(name)) && (!HasFunc(name)) )
@ -339,6 +417,9 @@ DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet)
return r; return r;
} }
if(!override_name.empty())
name=override_name;
CmdSet temp; CmdSet temp;
if(!pSet) if(!pSet)
{ {

View File

@ -102,11 +102,12 @@ public:
DefScript *GetScript(std::string); DefScript *GetScript(std::string);
unsigned int GetScripts(void); unsigned int GetScripts(void);
bool LoadScriptFromFile(std::string,std::string); bool LoadScriptFromFile(std::string,std::string);
DefReturnResult RunScript(std::string,CmdSet*); DefReturnResult RunScript(std::string name,CmdSet* pSet,std::string override_name="");
bool BoolRunScript(std::string,CmdSet*); bool BoolRunScript(std::string,CmdSet*);
unsigned int GetScriptID(std::string); unsigned int GetScriptID(std::string);
DefReturnResult RunSingleLine(std::string); DefReturnResult RunSingleLine(std::string);
bool ScriptExists(std::string); bool ScriptExists(std::string);
void DeleteScript(std::string);
VarSet variables; VarSet variables;
void SetPath(std::string); void SetPath(std::string);
bool LoadByName(std::string); bool LoadByName(std::string);

View File

@ -281,7 +281,7 @@ DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set)
return false; return false;
std::string dbname = stringToLower(Set.arg[0]); std::string dbname = stringToLower(Set.arg[0]);
// TODO: remove db if loading was not successful // TODO: remove db if loading was not successful
uint32 sections=((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).LoadFromFile((char*)Set.defaultarg.c_str()); uint32 sections=((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).LoadFromFile((char*)Set.defaultarg.c_str());
if(sections) if(sections)
{ {
logdetail("Loaded SCP: \"%s\" [%s] (%u sections)",dbname.c_str(),Set.defaultarg.c_str(),sections); logdetail("Loaded SCP: \"%s\" [%s] (%u sections)",dbname.c_str(),Set.defaultarg.c_str(),sections);
@ -296,7 +296,7 @@ DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set)
DefReturnResult DefScriptPackage::SCScpExists(CmdSet& Set) DefReturnResult DefScriptPackage::SCScpExists(CmdSet& Set)
{ {
return (!Set.defaultarg.empty()) && ((PseuInstance*)parentMethod)->HasSCPDatabase(Set.defaultarg); return (!Set.defaultarg.empty()) && ((PseuInstance*)parentMethod)->dbmgr.HasDB(Set.defaultarg);
} }
DefReturnResult DefScriptPackage::SCScpSectionExists(CmdSet& Set) DefReturnResult DefScriptPackage::SCScpSectionExists(CmdSet& Set)
@ -305,8 +305,8 @@ DefReturnResult DefScriptPackage::SCScpSectionExists(CmdSet& Set)
if(!Set.arg[0].empty()) if(!Set.arg[0].empty())
dbname=Set.arg[0]; dbname=Set.arg[0];
return (!Set.defaultarg.empty()) && (!dbname.empty()) return (!Set.defaultarg.empty()) && (!dbname.empty())
&& ((PseuInstance*)parentMethod)->HasSCPDatabase(dbname) && ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).HasField((uint32)DefScriptTools::toNumber(Set.defaultarg)); && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField((uint32)DefScriptTools::toNumber(Set.defaultarg));
} }
DefReturnResult DefScriptPackage::SCScpEntryExists(CmdSet& Set) DefReturnResult DefScriptPackage::SCScpEntryExists(CmdSet& Set)
@ -318,9 +318,9 @@ DefReturnResult DefScriptPackage::SCScpEntryExists(CmdSet& Set)
if(!Set.arg[1].empty()) if(!Set.arg[1].empty())
keyid=(uint32)DefScriptTools::toNumber(Set.arg[1]); keyid=(uint32)DefScriptTools::toNumber(Set.arg[1]);
return (!Set.defaultarg.empty()) && (!dbname.empty()) return (!Set.defaultarg.empty()) && (!dbname.empty())
&& ((PseuInstance*)parentMethod)->HasSCPDatabase(dbname) && ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).HasField(keyid) && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField(keyid)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).GetField(keyid).HasEntry(Set.defaultarg); && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).GetField(keyid).HasEntry(Set.defaultarg);
} }
@ -340,11 +340,11 @@ DefReturnResult DefScriptPackage::SCGetScpValue(CmdSet& Set)
if(!Set.defaultarg.empty()) if(!Set.defaultarg.empty())
entry=Set.defaultarg; entry=Set.defaultarg;
if( (!entry.empty()) && (!dbname.empty()) if( (!entry.empty()) && (!dbname.empty())
&& ((PseuInstance*)parentMethod)->HasSCPDatabase(dbname) && ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).HasField(keyid) && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField(keyid)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).GetField(keyid).HasEntry(entry)) && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).GetField(keyid).HasEntry(entry))
{ {
r.ret = ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).GetField(keyid).GetString(entry); r.ret = ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).GetField(keyid).GetString(entry);
} }
else else
{ {

View File

@ -238,19 +238,6 @@ void PseuInstance::Sleep(uint32 msecs)
GetRunnable()->sleep(msecs); GetRunnable()->sleep(msecs);
} }
SCPDatabase& PseuInstance::GetSCPDatabase(std::string dbname)
{
return _dbmap[dbname];
}
bool PseuInstance::HasSCPDatabase(std::string dbname)
{
for(std::map<std::string,SCPDatabase>::iterator i = _dbmap.begin(); i != _dbmap.end(); i++)
if(i->first == dbname)
return true;
return false;
}
PseuInstanceConf::PseuInstanceConf() PseuInstanceConf::PseuInstanceConf()
{ {
enablecli=false; enablecli=false;

View File

@ -72,8 +72,7 @@ class PseuInstance
void SetSessionKey(BigNumber key) { _sessionkey = key; } void SetSessionKey(BigNumber key) { _sessionkey = key; }
BigNumber GetSessionKey(void) { return _sessionkey; } BigNumber GetSessionKey(void) { return _sessionkey; }
void SetError(void) { _error = true; } void SetError(void) { _error = true; }
SCPDatabase& GetSCPDatabase(std::string); SCPDatabaseMgr dbmgr;
bool HasSCPDatabase(std::string);
bool Init(); bool Init();
void SaveAllCache(void); void SaveAllCache(void);
@ -103,8 +102,6 @@ class PseuInstance
SocketHandler _sh; SocketHandler _sh;
CliRunnable *_cli; CliRunnable *_cli;
ZThread::Thread _clithread; ZThread::Thread _clithread;
std::map<std::string,SCPDatabase> _dbmap;
}; };

View File

@ -81,3 +81,16 @@ uint32 SCPDatabase::GetFieldByValue(std::string entry, std::string value)
return fm->first; return fm->first;
return 0; return 0;
} }
bool SCPDatabaseMgr::HasDB(std::string n)
{
for(SCPDatabaseMap::iterator i = _map.begin(); i != _map.end(); i++)
if(i->first == n)
return true;
return false;
}
SCPDatabase& SCPDatabaseMgr::GetDB(std::string n)
{
return _map[n];
}

View File

@ -40,4 +40,16 @@ private:
}; };
typedef std::map<std::string,SCPDatabase> SCPDatabaseMap;
class SCPDatabaseMgr
{
public:
bool HasDB(std::string);
SCPDatabase& GetDB(std::string);
private:
SCPDatabaseMap _map;
};
#endif #endif

View File

@ -481,7 +481,7 @@ void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket)
else if(msg.length()<15 && (msg.find("omg")!=std::string::npos || msg.find("omfg")!=std::string::npos) ) else if(msg.length()<15 && (msg.find("omg")!=std::string::npos || msg.find("omfg")!=std::string::npos) )
SendChatMessage(CHAT_MSG_SAY,lang,"OMG a bot logged in, you don't believe it :O",""); SendChatMessage(CHAT_MSG_SAY,lang,"OMG a bot logged in, you don't believe it :O","");
else if(msg.find("from")!=std::string::npos || msg.find("download")!=std::string::npos) else if(msg.find("from")!=std::string::npos || msg.find("download")!=std::string::npos)
SendChatMessage(CHAT_MSG_SAY,lang,"you can dl me from http://my.opera.com/PseuWoW",""); SendChatMessage(CHAT_MSG_SAY,lang,"http://my.opera.com/PseuWoW","");
else if(msg.find("Genesis")!=std::string::npos || msg.find("genesis")!=std::string::npos) else if(msg.find("Genesis")!=std::string::npos || msg.find("genesis")!=std::string::npos)
SendChatMessage(CHAT_MSG_YELL,lang,"False.Genesis, they are calling you!! Come here, master xD",""); SendChatMessage(CHAT_MSG_YELL,lang,"False.Genesis, they are calling you!! Come here, master xD","");
} }

View File

@ -48,7 +48,7 @@ void WorldSocket::OnRead()
ASSERT(_remaining > 0); // case pktsize==0 is handled below ASSERT(_remaining > 0); // case pktsize==0 is handled below
if(ibuf.GetLength() < _remaining) if(ibuf.GetLength() < _remaining)
{ {
logerror("Delaying WorldPacket generation, bufsize is %u but should be >= %u",ibuf.GetLength(),_remaining); DEBUG(logdebug("Delaying WorldPacket generation, bufsize is %u but should be >= %u",ibuf.GetLength(),_remaining));
break; break;
} }
_gothdr=false; _gothdr=false;
@ -62,7 +62,7 @@ void WorldSocket::OnRead()
{ {
if(ibuf.GetLength() < sizeof(ServerPktHeader)) if(ibuf.GetLength() < sizeof(ServerPktHeader))
{ {
logerror("Delaying header reading, bufsize is %u but should be >= %u",ibuf.GetLength(),sizeof(ServerPktHeader)); DEBUG(logdebug("Delaying header reading, bufsize is %u but should be >= %u",ibuf.GetLength(),sizeof(ServerPktHeader)));
break; break;
} }
ServerPktHeader hdr; ServerPktHeader hdr;
@ -72,8 +72,8 @@ void WorldSocket::OnRead()
_opcode = hdr.cmd; _opcode = hdr.cmd;
if(_opcode > 800) // no opcode has yet a number over 800 if(_opcode > 800) // no opcode has yet a number over 800
{ {
logcritical("CRYPT ERROR: opcode=%u, remain=%u",_opcode,_remaining); logcritical("CRYPT ERROR: opcode=%u, remain=%u",_opcode,_remaining); // this should never be the case!
//GetSession()->GetInstance()->SetError(); // please test if this is stable!!! GetSession()->GetInstance()->SetError(); // no way to recover the crypt, must exit
// if the crypt gets messy its hardly possible to recover it, especially if we dont know // if the crypt gets messy its hardly possible to recover it, especially if we dont know
// the lentgh of the following data part // the lentgh of the following data part
// TODO: invent some way how to recover the crypt (reconnect?) // TODO: invent some way how to recover the crypt (reconnect?)