* 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 (len < CRYPTED_RECV_LEN) return;
_recv_i2=_recv_i;
_recv_j2=_recv_j;
for (size_t t = 0; t < CRYPTED_RECV_LEN; t++)
{
_recv_i %= _key.size();
@ -70,13 +67,6 @@ void AuthCrypt::SetKey(uint8 *key, size_t len)
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()
{
}

View File

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

View File

@ -10,6 +10,8 @@
using namespace DefScriptTools;
#define SN_ONLOAD "?onload?"
enum DefScriptBlockType
{
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++)
if(i->first == name && i->second != NULL)
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;
}
void DefScriptPackage::DeleteScript(std::string sn)
{
if(ScriptExists(sn))
{
delete GetScript(sn);
Script.erase(sn);
}
}
bool DefScriptPackage::LoadByName(std::string 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::fstream f;
bool load_debug=false,load_notify=false, exec=false;
bool load_debug=false,load_notify=false, exec=false, cantload=false;
char z;
f.open(fn.c_str(),std::ios_base::in);
if(!f.is_open())
return false;
std::deque<unsigned int> Blocks;
if(GetScript(sn))
delete GetScript(sn);
DefScript *newscript = new DefScript(this);
Script[sn] = newscript;
Script[sn]->SetName(sn); // necessary that the script knows its own name
DeleteScript(SN_ONLOAD);
while(!f.eof()){
line.clear();
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
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";
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(),"endif ",6)==0 || memcmp(line.c_str(),"endif\t",5)==0) line="endif";
else if(memcmp(line.c_str(),"loop ",5)==0 || memcmp(line.c_str(),"loop\t",5)==0) line="loop";
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")
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)
std::cout<<"~LOAD: "<<line<<"\n";
if(!exec)
Script[sn]->AddLine(line);
else
{
this->RunSingleLineFromScript(line,Script[sn]);
if(!ScriptExists(SN_ONLOAD))
Script[SN_ONLOAD] = new DefScript(this);
Script[SN_ONLOAD]->AddLine(line);
}
}
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)
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
DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet)
DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet,std::string override_name)
{
DefReturnResult r;
if( (!ScriptExists(name)) && (!HasFunc(name)) )
@ -339,6 +417,9 @@ DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet)
return r;
}
if(!override_name.empty())
name=override_name;
CmdSet temp;
if(!pSet)
{

View File

@ -102,11 +102,12 @@ public:
DefScript *GetScript(std::string);
unsigned int GetScripts(void);
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*);
unsigned int GetScriptID(std::string);
DefReturnResult RunSingleLine(std::string);
bool ScriptExists(std::string);
void DeleteScript(std::string);
VarSet variables;
void SetPath(std::string);
bool LoadByName(std::string);

View File

@ -281,7 +281,7 @@ DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set)
return false;
std::string dbname = stringToLower(Set.arg[0]);
// 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)
{
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)
{
return (!Set.defaultarg.empty()) && ((PseuInstance*)parentMethod)->HasSCPDatabase(Set.defaultarg);
return (!Set.defaultarg.empty()) && ((PseuInstance*)parentMethod)->dbmgr.HasDB(Set.defaultarg);
}
DefReturnResult DefScriptPackage::SCScpSectionExists(CmdSet& Set)
@ -305,8 +305,8 @@ DefReturnResult DefScriptPackage::SCScpSectionExists(CmdSet& Set)
if(!Set.arg[0].empty())
dbname=Set.arg[0];
return (!Set.defaultarg.empty()) && (!dbname.empty())
&& ((PseuInstance*)parentMethod)->HasSCPDatabase(dbname)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).HasField((uint32)DefScriptTools::toNumber(Set.defaultarg));
&& ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname)
&& ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField((uint32)DefScriptTools::toNumber(Set.defaultarg));
}
DefReturnResult DefScriptPackage::SCScpEntryExists(CmdSet& Set)
@ -318,9 +318,9 @@ DefReturnResult DefScriptPackage::SCScpEntryExists(CmdSet& Set)
if(!Set.arg[1].empty())
keyid=(uint32)DefScriptTools::toNumber(Set.arg[1]);
return (!Set.defaultarg.empty()) && (!dbname.empty())
&& ((PseuInstance*)parentMethod)->HasSCPDatabase(dbname)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).HasField(keyid)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).GetField(keyid).HasEntry(Set.defaultarg);
&& ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname)
&& ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField(keyid)
&& ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).GetField(keyid).HasEntry(Set.defaultarg);
}
@ -340,11 +340,11 @@ DefReturnResult DefScriptPackage::SCGetScpValue(CmdSet& Set)
if(!Set.defaultarg.empty())
entry=Set.defaultarg;
if( (!entry.empty()) && (!dbname.empty())
&& ((PseuInstance*)parentMethod)->HasSCPDatabase(dbname)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).HasField(keyid)
&& ((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).GetField(keyid).HasEntry(entry))
&& ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname)
&& ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField(keyid)
&& ((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
{

View File

@ -238,19 +238,6 @@ void PseuInstance::Sleep(uint32 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()
{
enablecli=false;

View File

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

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) )
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)
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)
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
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;
}
_gothdr=false;
@ -62,7 +62,7 @@ void WorldSocket::OnRead()
{
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;
}
ServerPktHeader hdr;
@ -72,8 +72,8 @@ void WorldSocket::OnRead()
_opcode = hdr.cmd;
if(_opcode > 800) // no opcode has yet a number over 800
{
logcritical("CRYPT ERROR: opcode=%u, remain=%u",_opcode,_remaining);
//GetSession()->GetInstance()->SetError(); // please test if this is stable!!!
logcritical("CRYPT ERROR: opcode=%u, remain=%u",_opcode,_remaining); // this should never be the case!
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
// the lentgh of the following data part
// TODO: invent some way how to recover the crypt (reconnect?)