last changes before 2.1.3:
* added script to support /me-like emotes (scriptname is "me")
* changed the permission system: now a script cant be used as game command f no permission is explicitly set
* implemented threadsafe CLI queue to solve crashes with short-intervalled events that ran on 2 threads
* fixed name return at "getitemprotovalue" script
* iplemented DrawObject class and a Mgr for those objects; they will ease object drawing once implemented. the Mgr works under control of the GUI thread and is threadsafe.
* implemented auto-loading of SCP files if a name-tag is present somewhere in the file ("#dbname=...") and no explicit db name was passed to "loadscp" script.
* changed internal ObjMgr storage to std::map (instead of list) for faster access
* fixed call of "_enterworld" script
* fixed handling of MyCharacter(), which could cause crashes after newly changes
* fixed GetFileList() func in tools.cpp (this fixes also related "lgetfiles" script func). now it will only parse files, not directories. might still need some fixing for linux.
This commit is contained in:
parent
15e24961ce
commit
3100f68a30
@ -1,23 +1,29 @@
|
||||
#permission=255
|
||||
|
||||
// PSEUWOW DEF_SCRIPT STARTUP FILE
|
||||
|
||||
LOG * DefScript StartUp [${@version_short}]...
|
||||
// this is for debugging which scripts are loaded
|
||||
// set to false to disable output
|
||||
SET,LoadDebug true
|
||||
|
||||
// first, load all scripts in patch 'scripts' with extension .def
|
||||
LOG *** DefScript StartUp [${@version_short}]...
|
||||
|
||||
// first, load all scripts in path 'scripts' with extension .def
|
||||
SET,fcount ?{LGETFILES,scriptlist,def scripts}
|
||||
LSORT scriptlist
|
||||
LOGDETAIL * Loading ${fcount} scripts.
|
||||
LOG *** Loading ${fcount} script files.
|
||||
// iterate over all files and load them; if counter i is equal to the amount of files we are done.
|
||||
SET,i 0
|
||||
SET,errors 0
|
||||
LOOP
|
||||
IF ?{EQUAL,${i} ${fcount}}
|
||||
EXITLOOP
|
||||
ENDIF
|
||||
SET,fn ./scripts/?{LINDEX,scriptlist ${i}}
|
||||
LOG *** Loading script file [${fn}]
|
||||
IF ?{AND,?{IsSet LoadDebug} ${LoadDebug}}
|
||||
LOG * Loading script file [${fn}]
|
||||
ENDIF
|
||||
IF ?{NOT ?{LOADDEF ${fn}}}
|
||||
LOGERROR Can't load script [${fn}]
|
||||
LOGERROR * Error loading [${fn}]
|
||||
ADD,errors 1
|
||||
ENDIF
|
||||
ADD,i 1
|
||||
ENDLOOP
|
||||
@ -28,12 +34,16 @@ UNSET i
|
||||
UNSET fn
|
||||
LDELETE scriptlist
|
||||
|
||||
IF ?{NOT ${errors}}
|
||||
LOG *** All files loaded without errors.
|
||||
ELSE
|
||||
LOG *** All files loaded, ${errors} errors.
|
||||
ENDIF
|
||||
UNSET errors
|
||||
|
||||
// loads & applies the configuration
|
||||
CONFIG
|
||||
|
||||
// set permissions for internal functions
|
||||
INTERNAL_PERM
|
||||
|
||||
// Load some SCP files
|
||||
LOADALLSCP
|
||||
|
||||
|
||||
@ -208,3 +208,22 @@ ELSE
|
||||
YELL,{${@0}} ${@def}
|
||||
RETURN true
|
||||
ENDIF
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
#script=me
|
||||
#permission=0
|
||||
//----------------------------------------------------------
|
||||
// Send text emote. example: "me feels lolo" will result in "Pseuwow feels lolo" at other clients
|
||||
SET,lang ${@0}
|
||||
SET,msg ${@def}
|
||||
|
||||
DEFAULT,#DEFAULTLANG ?{GETSCPVALUE,race,{${@myrace}} faction}
|
||||
DEFAULT,lang ${#DEFAULTLANG}
|
||||
|
||||
LOGDEBUG * Me ${msg} (in lang ${lang})
|
||||
|
||||
SENDCHATMESSAGE,8,${lang},{${msg}}
|
||||
UNSET lang
|
||||
UNSET msg
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
//--------------------------------------------------------
|
||||
#script=append
|
||||
#permission=255
|
||||
//--------------------------------------------------------
|
||||
// usage: append text to a string.
|
||||
// args:
|
||||
@ -53,13 +52,13 @@ LOADSCP,race data/scp/race.scp
|
||||
// load extended databases if present.
|
||||
EXLOADSCP,sound data/scp/sound.scp
|
||||
EXLOADSCP,emote data/scp/emote.scp
|
||||
EXLOADSCP,area data/scp/area.scp
|
||||
|
||||
LOG * SCP loaded.
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
#script=string_is_command
|
||||
#permission=255
|
||||
//-------------------------------------------------
|
||||
// purpose: detect if @def might be a server command.
|
||||
|
||||
@ -80,7 +79,6 @@ return false
|
||||
|
||||
//--------------------------------------------------------
|
||||
#script=normalize_name
|
||||
#permission=255
|
||||
//--------------------------------------------------------
|
||||
// uppercases first char, lowercases rest
|
||||
set,name ?{uppercase ?{substr,1 ${@def}}}
|
||||
@ -91,7 +89,6 @@ return ${name}
|
||||
|
||||
//---------------------------------------------------------
|
||||
#script=globname
|
||||
#permission=255
|
||||
//---------------------------------------------------------
|
||||
// purpose: returns the global name of a variable
|
||||
// args: @def: var name, @0 (optional): name of the intended parent func
|
||||
@ -107,7 +104,6 @@ return #${top}::${@def}
|
||||
|
||||
//---------------------------------------------------------
|
||||
#script=getvar
|
||||
#permission=255
|
||||
//---------------------------------------------------------
|
||||
// purpose: returns the value of a variable. if the variable hasnt been set return empty string.
|
||||
set,top ${@caller}
|
||||
@ -120,4 +116,26 @@ if ?{isset ${v}}
|
||||
endif
|
||||
return
|
||||
|
||||
//---------------------------------------------------------
|
||||
#script=reverse
|
||||
//---------------------------------------------------------
|
||||
// purpose: reverse a srtring
|
||||
// args: @def: string to reverse
|
||||
// returns: reversed string
|
||||
|
||||
set,outstr
|
||||
set,elems ?{lsplit,mylist ${@def}}
|
||||
set,i ${elems}
|
||||
loop
|
||||
sub,i 1
|
||||
if ?{equal,${i} -1}
|
||||
exitloop
|
||||
endif
|
||||
append,outstr ?{lindex,mylist ${i}}
|
||||
endloop
|
||||
ldelete mylist
|
||||
return ${outstr}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@ return ${t}
|
||||
|
||||
//------------------------------------------------
|
||||
#script=toleet
|
||||
#permission=255
|
||||
//------------------------------------------------
|
||||
// purpose: convert any text into leetspeak [1337sp34k]
|
||||
// args: @def: the text to convert
|
||||
|
||||
@ -39,6 +39,7 @@ LOGDETAIL * Dangerous variables removed.
|
||||
//-----------------------------------------------
|
||||
// Load all conf files from directory /conf/
|
||||
// get all *.conf file names from /conf/ directory, store the names in list 'fl' and the amount in 'fcount'
|
||||
LOG ** Configuring PseuWoW...
|
||||
SET,fcount ?{LGETFILES,fl,conf conf}
|
||||
// sort the list, load conf files alphabetically.
|
||||
LSORT fl
|
||||
@ -76,9 +77,14 @@ APPLYPERMISSIONS
|
||||
// remove dangerous variables
|
||||
CLEANUPVARS
|
||||
|
||||
// set permissions for internal functions
|
||||
INTERNAL_PERM
|
||||
|
||||
// if its not set in the conf file, default it to "." (WoWEmu & MaNGOS style)
|
||||
DEFAULT,#CMDCHAR .
|
||||
|
||||
LOG ** All Config done.
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
#script=internal_perm
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
//--------------------------------------------
|
||||
#script=lcontains
|
||||
#permission=255
|
||||
//--------------------------------------------
|
||||
// return true if any list element matches @def, else return false.
|
||||
// @0: list name, @def: search string
|
||||
@ -18,7 +17,6 @@ endif
|
||||
|
||||
set,result false
|
||||
loop
|
||||
out eq:?{equal,${i} ?{llen ${l}}} i:${i} len:?{llen ${l}}
|
||||
if ?{equal,${i} ?{llen ${l}}}
|
||||
exitloop
|
||||
endif
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
//------------------------------------------------
|
||||
#script=gc
|
||||
#permission=0
|
||||
//------------------------------------------------
|
||||
// example script to write into channel "generalchat"
|
||||
// usage: "gc bla bla..."
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
#permission=255
|
||||
|
||||
// GETS EXECUTED IF A PLAYER TRIES TO GIVE PSEUWOW A COMMAND AND IS NOT ALLOWED TO
|
||||
// this script gets executed if a player tries to give pseuwow a command but is not allowed to
|
||||
|
||||
// Arguments:
|
||||
// ==========
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#permission=255
|
||||
|
||||
// EXECUTED EVERYTIME A WHISPER IS BEEING RECIEVED
|
||||
|
||||
// comment out the following line if you dont need it
|
||||
|
||||
@ -32,16 +32,11 @@ void CliRunnable::run(void)
|
||||
if(in[0]=='!')
|
||||
cur = &in[1];
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
out = cur.empty() ? in : (cur+" "+in);
|
||||
_instance->GetScripts()->RunSingleLine(out);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
printf("Exception while executing CLI command!\n");
|
||||
}
|
||||
_instance->AddCliCommand(out);
|
||||
// add delay just if necessary
|
||||
//ZThread::Thread::sleep(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ bool VarSet::ReadVarsFromFile(std::string fn)
|
||||
unsigned int pos=line.find("=");
|
||||
if(pos!=std::string::npos)
|
||||
{
|
||||
std::string v=line.substr(0,pos);;
|
||||
std::string v=line.substr(0,pos);
|
||||
|
||||
if(upper)
|
||||
v=toUpper(v);
|
||||
|
||||
@ -297,12 +297,22 @@ DefReturnResult DefScriptPackage::SCtarget(CmdSet& Set)
|
||||
|
||||
DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set)
|
||||
{
|
||||
DefReturnResult r;
|
||||
if(Set.arg[0].empty() || Set.defaultarg.empty())
|
||||
SCPDatabaseMgr& dbmgr = ((PseuInstance*)parentMethod)->dbmgr;
|
||||
if(Set.defaultarg.empty()) // exit if no filename was given
|
||||
return false;
|
||||
std::string dbname = stringToLower(Set.arg[0]);
|
||||
// TODO: remove db if loading was not successful
|
||||
uint32 sections=((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).LoadFromFile((char*)Set.defaultarg.c_str());
|
||||
uint32 sections = 0;
|
||||
if(dbname.empty()) // if no db name was supplied, try to find it automatically in the file ("#dbname=...")
|
||||
{
|
||||
sections = dbmgr.AutoLoadFile((char*)Set.defaultarg.c_str());
|
||||
if(!sections)
|
||||
{
|
||||
logerror("Tried to auto-load SCP file: \"%s\", but no name tag found. skipped.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sections = 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);
|
||||
@ -311,8 +321,8 @@ DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set)
|
||||
{
|
||||
logerror("Failed to load SCP: \"%s\" [%s]",dbname.c_str(),Set.defaultarg.c_str());
|
||||
}
|
||||
r.ret=toString((uint64)sections);
|
||||
return r;
|
||||
}
|
||||
return toString((uint64)sections);;
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::SCScpExists(CmdSet& Set)
|
||||
@ -519,10 +529,10 @@ DefReturnResult DefScriptPackage::SCGetItemProtoValue(CmdSet& Set)
|
||||
uint32 tmp=0;
|
||||
if(t=="class") r.ret=toString(proto->Class);
|
||||
else if(t=="subclass") r.ret=toString(proto->SubClass);
|
||||
else if(t=="name1" || t=="name") proto->Name[0];
|
||||
else if(t=="name2") proto->Name[1];
|
||||
else if(t=="name3") proto->Name[2];
|
||||
else if(t=="name4") proto->Name[3];
|
||||
else if(t=="name1" || t=="name") r.ret=proto->Name[0];
|
||||
else if(t=="name2") r.ret=proto->Name[1];
|
||||
else if(t=="name3") r.ret=proto->Name[2];
|
||||
else if(t=="name4") r.ret=proto->Name[3];
|
||||
else if(t=="model" || t=="displayid") r.ret=toString(proto->DisplayInfoID);
|
||||
else if(t=="quality") r.ret=toString(proto->Quality);
|
||||
else if(t=="flags") r.ret=toString(proto->Flags);
|
||||
@ -766,7 +776,7 @@ void DefScriptPackage::My_LoadUserPermissions(VarSet &vs)
|
||||
|
||||
void DefScriptPackage::My_Run(std::string line, std::string username)
|
||||
{
|
||||
uint8 scperm=255; // builtin functions that have no explicit req. permission level assigned should be secure from beeing called
|
||||
int16 scperm = -1; // builtin functions that have no explicit req. permission level assigned should be secure from beeing called from ingame
|
||||
uint8 usrperm=0; // users/players that have no explicit permission assigned should have minimal permission
|
||||
|
||||
for (std::map<std::string,unsigned char>::iterator i = my_usrPermissionMap.begin(); i != my_usrPermissionMap.end(); i++)
|
||||
@ -778,9 +788,8 @@ void DefScriptPackage::My_Run(std::string line, std::string username)
|
||||
}
|
||||
|
||||
DefXChgResult final;
|
||||
if(usrperm < 255)
|
||||
if(usrperm < 255 && line.find("?{")!=std::string::npos)
|
||||
{
|
||||
if(line.find("?{")!=std::string::npos)
|
||||
logerror("WARNING: %s wanted to exec \"%s\"",username.c_str(),line.c_str());
|
||||
final=ReplaceVars(line,NULL,0,false); // prevent execution of embedded scripts (= using return values) that could trigger dangerous stuff.
|
||||
}
|
||||
@ -799,6 +808,9 @@ void DefScriptPackage::My_Run(std::string line, std::string username)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(scperm > 0) // skip "invisible" scripts (without any permission set) completely.
|
||||
{
|
||||
if(usrperm < scperm)
|
||||
{
|
||||
CmdSet Set;
|
||||
@ -809,6 +821,8 @@ void DefScriptPackage::My_Run(std::string line, std::string username)
|
||||
RunScript("_nopermission",&Set);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Interpret(curSet);
|
||||
}
|
||||
|
||||
67
src/Client/GUI/DrawObjMgr.cpp
Normal file
67
src/Client/GUI/DrawObjMgr.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "DrawObject.h"
|
||||
#include "DrawObjMgr.h"
|
||||
|
||||
DrawObjMgr::DrawObjMgr()
|
||||
{
|
||||
DEBUG( logdebug("DrawObjMgr created") );
|
||||
}
|
||||
|
||||
DrawObjMgr::~DrawObjMgr()
|
||||
{
|
||||
DEBUG( logdebug("~DrawObjMgr(), deleting %u DrawObjects...", _storage.size() ) );
|
||||
for(DrawObjStorage::iterator i = _storage.begin(); i != _storage.end(); i++)
|
||||
{
|
||||
DEBUG( logdebug("del for guid "I64FMT, i->first) );
|
||||
delete i->second; // this can be done safely, since the object ptrs are not accessed
|
||||
}
|
||||
}
|
||||
|
||||
void DrawObjMgr::Add(uint64 objguid, DrawObject *o)
|
||||
{
|
||||
_add.add(std::pair<uint64,DrawObject*>(objguid,o));
|
||||
}
|
||||
|
||||
void DrawObjMgr::Delete(uint64 guid)
|
||||
{
|
||||
_del.add(guid);
|
||||
}
|
||||
|
||||
void DrawObjMgr::Update(void)
|
||||
{
|
||||
ZThread::FastMutex mut;
|
||||
|
||||
// now for the threadsafe part: lock every thread except this one
|
||||
// to prevent obj ptr corruption caused by other running threads
|
||||
// TODO: lock only main thread (that should be the only one to delete objects anyway!)
|
||||
mut.acquire();
|
||||
|
||||
// add objects waiting on the add queue to the real storage
|
||||
while(_add.size())
|
||||
{
|
||||
std::pair<uint64,DrawObject*> p = _add.next();
|
||||
_storage[p.first] = p.second;
|
||||
}
|
||||
|
||||
// same for objects that should be deleted
|
||||
while(_del.size())
|
||||
{
|
||||
uint64 guid = _del.next();
|
||||
if(_storage.find(guid) != _storage.end())
|
||||
{
|
||||
DrawObject *o = _storage[guid];
|
||||
_storage.erase(guid);
|
||||
delete o;
|
||||
}
|
||||
}
|
||||
|
||||
// now draw everything
|
||||
for(DrawObjStorage::iterator i = _storage.begin(); i != _storage.end(); i++)
|
||||
{
|
||||
i->second->Draw();
|
||||
}
|
||||
|
||||
mut.release();
|
||||
|
||||
}
|
||||
27
src/Client/GUI/DrawObjMgr.h
Normal file
27
src/Client/GUI/DrawObjMgr.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef DRAWOBJMGR_H
|
||||
#define DRAWOBJMGR_H
|
||||
|
||||
#include <utility>
|
||||
|
||||
class DrawObject;
|
||||
|
||||
typedef std::map<uint64,DrawObject*> DrawObjStorage;
|
||||
|
||||
class DrawObjMgr
|
||||
{
|
||||
public:
|
||||
DrawObjMgr();
|
||||
~DrawObjMgr();
|
||||
void Add(uint64,DrawObject*);
|
||||
void Delete(uint64);
|
||||
void Update(void); // Threadsafe! delete code must be called from here!
|
||||
uint32 StorageSize(void) { return _storage.size(); }
|
||||
|
||||
private:
|
||||
DrawObjStorage _storage;
|
||||
ZThread::LockedQueue<uint64,ZThread::FastMutex> _del;
|
||||
ZThread::LockedQueue<std::pair<uint64,DrawObject*>,ZThread::FastMutex > _add;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
21
src/Client/GUI/DrawObject.cpp
Normal file
21
src/Client/GUI/DrawObject.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "common.h"
|
||||
#include "PseuGui.h"
|
||||
#include "DrawObject.h"
|
||||
#include "PseuWoW.h"
|
||||
|
||||
DrawObject::DrawObject(irr::scene::ISceneManager *smgr, Object *obj)
|
||||
{
|
||||
_smgr = smgr;
|
||||
_obj = obj;
|
||||
DEBUG( logdebug("create DrawObject() this=%X obj=%X smgr=%X",this,_obj,_smgr) );
|
||||
}
|
||||
|
||||
DrawObject::~DrawObject()
|
||||
{
|
||||
DEBUG( logdebug("~DrawObject() this=%X obj=%X smgr=%X",this,_obj,_smgr) );
|
||||
}
|
||||
|
||||
void DrawObject::Draw(void)
|
||||
{
|
||||
|
||||
}
|
||||
23
src/Client/GUI/DrawObject.h
Normal file
23
src/Client/GUI/DrawObject.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef DRAWOBJECT_H
|
||||
#define DRAWOBJECT_H
|
||||
|
||||
#include "common.h"
|
||||
#include "irrlicht/irrlicht.h"
|
||||
|
||||
class Object;
|
||||
|
||||
class DrawObject
|
||||
{
|
||||
public:
|
||||
DrawObject(irr::scene::ISceneManager*, Object*);
|
||||
~DrawObject();
|
||||
void Draw(void); // call only in threadsafe environment!! (ensure the obj ptr is still valid!)
|
||||
// additionally, we dont use a GetObject() func - that would fuck things up if the object was already deleted.
|
||||
|
||||
private:
|
||||
Object *_obj;
|
||||
irr::scene::ISceneManager *_smgr;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,5 +1,7 @@
|
||||
#include "common.h"
|
||||
#include "irrlicht/irrlicht.h"
|
||||
#include "Object.h"
|
||||
#include "DrawObject.h"
|
||||
#include "PseuWoW.h"
|
||||
#include "PseuGUI.h"
|
||||
|
||||
@ -55,12 +57,8 @@ PseuGUI::PseuGUI()
|
||||
|
||||
PseuGUI::~PseuGUI()
|
||||
{
|
||||
this->Shutdown();
|
||||
}
|
||||
|
||||
void PseuGUI::SetInstance(PseuInstance *i)
|
||||
{
|
||||
_instance = i;
|
||||
this->Cancel();
|
||||
_instance->DeleteGUI(); // this makes the instance set its gui ptr to NULL
|
||||
}
|
||||
|
||||
void PseuGUI::SetDriver(uint8 driverId)
|
||||
@ -114,9 +112,9 @@ void PseuGUI::_Init(void)
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void PseuGUI::Shutdown(void)
|
||||
void PseuGUI::Cancel(void)
|
||||
{
|
||||
DEBUG(logdebug("PseuGUI::Shutdown()"));
|
||||
DEBUG(logdebug("PseuGUI::Cancel()"));
|
||||
_mustdie = true;
|
||||
if(_device)
|
||||
{
|
||||
@ -125,6 +123,12 @@ void PseuGUI::Shutdown(void)
|
||||
}
|
||||
}
|
||||
|
||||
void PseuGUI::Shutdown(void)
|
||||
{
|
||||
DEBUG(logdebug("PseuGUI::Shutdown()"));
|
||||
_mustdie = true;
|
||||
}
|
||||
|
||||
void PseuGUI::Run(void)
|
||||
{
|
||||
if(!_initialized)
|
||||
@ -140,11 +144,21 @@ void PseuGUI::Run(void)
|
||||
{
|
||||
_device->sleep(10); // save cpu & gpu power if not focused
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_driver->beginScene(true, true, 0);
|
||||
|
||||
domgr.Update(); // iterate over DrawObjects, draw them and clean up
|
||||
|
||||
_smgr->drawAll();
|
||||
|
||||
_driver->endScene();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
logerror("Unhandled exception in PseuGUI::Run() device=%X smgr=%X objects:%u", _device, _smgr, domgr.StorageSize());
|
||||
}
|
||||
|
||||
fps = _driver->getFPS();
|
||||
|
||||
@ -163,7 +177,25 @@ void PseuGUI::Run(void)
|
||||
|
||||
}
|
||||
DEBUG(logdebug("PseuGUI::Run() finished"));
|
||||
Shutdown();
|
||||
Cancel(); // already got shut down somehow, we can now safely cancel and drop the device
|
||||
}
|
||||
|
||||
// called from ObjMgr::Remove(guid)
|
||||
void PseuGUI::NotifyObjectDeletion(uint64 guid)
|
||||
{
|
||||
domgr.Delete(guid);
|
||||
}
|
||||
|
||||
// called from ObjMgr::Add(Object*)
|
||||
void PseuGUI::NotifyObjectCreation(Object *o)
|
||||
{
|
||||
DrawObject *d = new DrawObject(_smgr,o);
|
||||
domgr.Add(o->GetGUID(),d);
|
||||
}
|
||||
|
||||
void PseuGUI::SetInstance(PseuInstance* in)
|
||||
{
|
||||
_instance = in;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2,11 +2,12 @@
|
||||
#define PSEUGUI_H
|
||||
|
||||
#include "irrlicht/irrlicht.h"
|
||||
#include "DrawObjMgr.h"
|
||||
|
||||
class PseuGUI;
|
||||
class Object;
|
||||
class PseuInstance;
|
||||
|
||||
|
||||
class PseuGUIRunnable : public ZThread::Runnable
|
||||
{
|
||||
public:
|
||||
@ -25,26 +26,33 @@ public:
|
||||
PseuGUI();
|
||||
~PseuGUI();
|
||||
|
||||
void Run(void);
|
||||
void SetInstance(PseuInstance*);
|
||||
void Run(void);
|
||||
void SetDriver(uint8);
|
||||
void SetResolution(uint16 x, uint16 y, uint16 depth=32);
|
||||
void SetWindowed(bool);
|
||||
void SetVSync(bool);
|
||||
void UseShadows(bool);
|
||||
void Cancel(void);
|
||||
void Shutdown(void);
|
||||
inline bool MustDie(void) { return _mustdie; }
|
||||
|
||||
// interfaces to tell the gui what to draw
|
||||
void NotifyObjectDeletion(uint64 guid);
|
||||
void NotifyObjectCreation(Object *o);
|
||||
|
||||
private:
|
||||
void _Init(void);
|
||||
uint16 _xres,_yres,_colordepth;
|
||||
bool _windowed,_vsync,_shadows;
|
||||
bool _initialized,_mustdie;
|
||||
PseuInstance *_instance;
|
||||
irr::IrrlichtDevice *_device;
|
||||
irr::video::IVideoDriver* _driver;
|
||||
irr::scene::ISceneManager* _smgr;
|
||||
irr::gui::IGUIEnvironment* _guienv;
|
||||
irr::video::E_DRIVER_TYPE _driverType;
|
||||
DrawObjMgr domgr;
|
||||
PseuInstance *_instance;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ void PseuInstanceRunnable::run(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
getchar();
|
||||
getchar(); // if init failed, wait for keypress before exit
|
||||
}
|
||||
delete _i;
|
||||
}
|
||||
@ -54,6 +54,8 @@ PseuInstance::PseuInstance(PseuInstanceRunnable *run)
|
||||
_conf=NULL;
|
||||
_cli=NULL;
|
||||
_rmcontrol=NULL;
|
||||
_gui=NULL;
|
||||
_guithread=NULL;
|
||||
_stop=false;
|
||||
_fastquit=false;
|
||||
_startrealm=true;
|
||||
@ -61,7 +63,6 @@ PseuInstance::PseuInstance(PseuInstanceRunnable *run)
|
||||
_error=false;
|
||||
_initialized=false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
PseuInstance::~PseuInstance()
|
||||
@ -72,6 +73,11 @@ PseuInstance::~PseuInstance()
|
||||
// delete _cli; // ok this is a little mem leak... can be fixed sometime in future
|
||||
}
|
||||
|
||||
if(_gui)
|
||||
_gui->Shutdown();
|
||||
if(_guithread)
|
||||
_guithread->wait();
|
||||
|
||||
if(_rmcontrol)
|
||||
delete _rmcontrol;
|
||||
if(_rsession)
|
||||
@ -94,7 +100,7 @@ bool PseuInstance::Init(void) {
|
||||
if(_confdir.empty())
|
||||
_confdir="./conf/";
|
||||
if(_scpdir.empty())
|
||||
_scpdir="./scp/";
|
||||
_scpdir="./scripts/";
|
||||
|
||||
srand((unsigned)time(NULL));
|
||||
RAND_set_rand_method(RAND_SSLeay()); // init openssl randomizer
|
||||
@ -138,13 +144,13 @@ bool PseuInstance::Init(void) {
|
||||
if(x>0 && y>0 && (depth==16 || depth==32) && driver>0 && driver<=5)
|
||||
{
|
||||
PseuGUIRunnable *rgui = new PseuGUIRunnable();
|
||||
PseuGUI *gui = rgui->GetGUI();
|
||||
gui->SetInstance(this);
|
||||
gui->SetDriver(driver);
|
||||
gui->SetResolution(x,y,depth);
|
||||
gui->SetVSync(vsync);
|
||||
gui->UseShadows(shadows);
|
||||
ZThread::Thread *t = new ZThread::Thread(rgui);
|
||||
_gui = rgui->GetGUI();
|
||||
_gui->SetInstance(this);
|
||||
_gui->SetDriver(driver);
|
||||
_gui->SetResolution(x,y,depth);
|
||||
_gui->SetVSync(vsync);
|
||||
_gui->UseShadows(shadows);
|
||||
_guithread = new ZThread::Thread(rgui);
|
||||
}
|
||||
else
|
||||
logerror("GUI: incorrect settings!");
|
||||
@ -232,6 +238,10 @@ void PseuInstance::Run(void)
|
||||
|
||||
void PseuInstance::Update()
|
||||
{
|
||||
// if the user typed anything into the console, process it before anything else
|
||||
if(_cli) // need to to process only if cli exists
|
||||
ProcessCliQueue();
|
||||
|
||||
// delete sessions if they are no longer needed
|
||||
if(_rsession && _rsession->MustDie())
|
||||
{
|
||||
@ -290,6 +300,28 @@ void PseuInstance::Update()
|
||||
this->Sleep(GetConf()->networksleeptime);
|
||||
}
|
||||
|
||||
void PseuInstance::ProcessCliQueue(void)
|
||||
{
|
||||
std::string cmd;
|
||||
while(_cliQueue.size())
|
||||
{
|
||||
cmd = _cliQueue.next();
|
||||
try
|
||||
{
|
||||
GetScripts()->RunSingleLine(cmd);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
logerror("Exception while executing CLI command: \"%s\"",cmd.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PseuInstance::AddCliCommand(std::string cmd)
|
||||
{
|
||||
_cliQueue.add(cmd);
|
||||
}
|
||||
|
||||
void PseuInstance::SaveAllCache(void)
|
||||
{
|
||||
//...
|
||||
@ -306,6 +338,12 @@ void PseuInstance::Sleep(uint32 msecs)
|
||||
GetRunnable()->sleep(msecs);
|
||||
}
|
||||
|
||||
void PseuInstance::DeleteGUI(void)
|
||||
{
|
||||
_gui = NULL;
|
||||
_guithread = NULL;
|
||||
}
|
||||
|
||||
PseuInstanceConf::PseuInstanceConf()
|
||||
{
|
||||
enablecli=false;
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include "DefScript/DefScript.h"
|
||||
#include "Network/SocketHandler.h"
|
||||
#include "SCPDatabase.h"
|
||||
#include "GUI/PseuGUI.h"
|
||||
|
||||
class RealmSession;
|
||||
class WorldSession;
|
||||
@ -64,45 +65,51 @@ class PseuInstanceConf
|
||||
|
||||
class PseuInstance
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
PseuInstance(PseuInstanceRunnable *run);
|
||||
~PseuInstance();
|
||||
|
||||
|
||||
WorldSession *GetWSession(void) { return _wsession; }
|
||||
RealmSession *GetRSession(void) { return _rsession; }
|
||||
PseuInstanceConf *GetConf(void) { return _conf; }
|
||||
DefScriptPackage *GetScripts(void) { return _scp; }
|
||||
PseuInstanceRunnable *GetRunnable(void) { return _runnable; }
|
||||
void SetConfDir(std::string dir) { _confdir = dir; }
|
||||
std::string GetConfDir(void) { return _confdir; }
|
||||
void SetScpDir(std::string dir) { _scpdir = dir; }
|
||||
void SetSessionKey(BigNumber key) { _sessionkey = key; }
|
||||
BigNumber GetSessionKey(void) { return _sessionkey; }
|
||||
void SetError(void) { _error = true; }
|
||||
inline WorldSession *GetWSession(void) { return _wsession; }
|
||||
inline RealmSession *GetRSession(void) { return _rsession; }
|
||||
inline PseuInstanceConf *GetConf(void) { return _conf; }
|
||||
inline DefScriptPackage *GetScripts(void) { return _scp; }
|
||||
inline PseuInstanceRunnable *GetRunnable(void) { return _runnable; }
|
||||
inline PseuGUI *GetGUI(void) { return _gui; }
|
||||
void DeleteGUI(void);
|
||||
|
||||
inline void SetConfDir(std::string dir) { _confdir = dir; }
|
||||
inline std::string GetConfDir(void) { return _confdir; }
|
||||
inline void SetScpDir(std::string dir) { _scpdir = dir; }
|
||||
inline void SetSessionKey(BigNumber key) { _sessionkey = key; }
|
||||
inline BigNumber GetSessionKey(void) { return _sessionkey; }
|
||||
inline void SetError(void) { _error = true; }
|
||||
SCPDatabaseMgr dbmgr;
|
||||
|
||||
bool Init();
|
||||
void SaveAllCache(void);
|
||||
void Stop(void) { _stop = true; }
|
||||
bool Stopped(void) { return _stop; }
|
||||
void SetFastQuit(bool q=true) { _fastquit=true; }
|
||||
inline void Stop(void) { _stop = true; }
|
||||
inline bool Stopped(void) { return _stop; }
|
||||
inline void SetFastQuit(bool q=true) { _fastquit=true; }
|
||||
void Quit(void);
|
||||
void Run(void);
|
||||
void Update(void);
|
||||
void Sleep(uint32 msecs);
|
||||
|
||||
void CreateWorldSession(void) { _createws = true; }
|
||||
inline void CreateWorldSession(void) { _createws = true; }
|
||||
|
||||
private:
|
||||
void ProcessCliQueue(void);
|
||||
void AddCliCommand(std::string);
|
||||
|
||||
private:
|
||||
|
||||
PseuInstanceRunnable *_runnable;
|
||||
RealmSession *_rsession;
|
||||
WorldSession *_wsession;
|
||||
PseuInstanceConf *_conf;
|
||||
DefScriptPackage *_scp;
|
||||
std::string _confdir,_scpdir;
|
||||
std::string _confdir,_scpdir; // _scpdir is the scipts dir, and NOT where SCP files are stored!!
|
||||
bool _initialized;
|
||||
bool _stop,_fastquit;
|
||||
bool _startrealm;
|
||||
@ -114,6 +121,9 @@ class PseuInstance
|
||||
CliRunnable *_cli;
|
||||
ZThread::Thread _clithread;
|
||||
RemoteController *_rmcontrol;
|
||||
ZThread::LockedQueue<std::string,ZThread::FastMutex> _cliQueue;
|
||||
PseuGUI *_gui;
|
||||
ZThread::Thread *_guithread;
|
||||
|
||||
};
|
||||
|
||||
@ -123,7 +133,7 @@ public:
|
||||
PseuInstanceRunnable();
|
||||
void run(void);
|
||||
void sleep(uint32);
|
||||
PseuInstance *GetInstance(void) { return _i; }
|
||||
inline PseuInstance *GetInstance(void) { return _i; }
|
||||
|
||||
private:
|
||||
PseuInstance *_i;
|
||||
|
||||
@ -2,30 +2,48 @@
|
||||
#include "common.h"
|
||||
#include "SCPDatabase.h"
|
||||
|
||||
|
||||
uint32 SCPDatabase::LoadFromFile(char *fn)
|
||||
{
|
||||
std::fstream fh;
|
||||
std::string line,value,entry,storage;
|
||||
uint32 id=0,sections=0;
|
||||
char c;
|
||||
uint32 size = GetFileSize(fn);
|
||||
if(!size)
|
||||
return 0;
|
||||
|
||||
fh.open(fn,std::ios_base::in);
|
||||
fh.open(fn,std::ios_base::in | std::ios_base::binary);
|
||||
if( !fh.is_open() )
|
||||
return 0;
|
||||
while(!fh.eof())
|
||||
|
||||
char *buf = new char[size];
|
||||
fh.read(buf,size);
|
||||
fh.close();
|
||||
|
||||
uint32 sections = LoadFromMem(buf,size);
|
||||
delete [] buf;
|
||||
return sections;
|
||||
}
|
||||
|
||||
|
||||
uint32 SCPDatabase::LoadFromMem(char *buf, uint32 size)
|
||||
{
|
||||
std::string line,value,entry,storage;
|
||||
uint32 id=0,sections=0;
|
||||
|
||||
for(uint32 pos = 0; pos < size; pos++)
|
||||
{
|
||||
c=fh.get();
|
||||
if(c=='\n' || fh.eof())
|
||||
if(buf[pos] == '\n')
|
||||
{
|
||||
if(line.empty())
|
||||
continue;
|
||||
while(line[0]==' ' || line[0]=='\t')
|
||||
line.erase(0,1);
|
||||
if(line.empty() || (line.length() > 1 && (line[0]=='/' && line[1]=='/')) )
|
||||
if(line.empty() || (line.length() > 1 && (line[0]=='#' || (line[0]=='/' && line[1]=='/'))) )
|
||||
{
|
||||
line.clear();
|
||||
continue;
|
||||
}
|
||||
if(line[line.size()-1] == 13) // this fixes the annoying newline problems on windows + binary mode
|
||||
line[line.size()-1] = 0;
|
||||
if(line[0]=='[')
|
||||
{
|
||||
id=(uint32)toInt(line.c_str()+1); // start reading after '['
|
||||
@ -45,9 +63,8 @@ uint32 SCPDatabase::LoadFromFile(char *fn)
|
||||
line.clear();
|
||||
}
|
||||
else
|
||||
line+=c; // fill up line until a newline is reached (see above)
|
||||
line += buf[pos]; // fill up line until a newline is reached (see above)
|
||||
}
|
||||
fh.close();
|
||||
return sections;
|
||||
}
|
||||
|
||||
@ -73,10 +90,7 @@ bool SCPField::HasEntry(std::string e)
|
||||
std::string SCPField::GetString(std::string entry)
|
||||
{
|
||||
//return HasEntry(entry) ? _map[entry] : "";
|
||||
if(HasEntry(entry))
|
||||
return _map[entry];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
// note that this can take a while depending on the size of the database!
|
||||
@ -101,11 +115,64 @@ SCPDatabase& SCPDatabaseMgr::GetDB(std::string n)
|
||||
return _map[n];
|
||||
}
|
||||
|
||||
uint32 SCPDatabaseMgr::AutoLoadFile(char *fn)
|
||||
{
|
||||
std::fstream fh;
|
||||
uint32 size = GetFileSize(fn);
|
||||
if(!size)
|
||||
return 0;
|
||||
|
||||
fh.open(fn,std::ios_base::in | std::ios_base::binary);
|
||||
if( !fh.is_open() )
|
||||
return 0;
|
||||
|
||||
char *buf = new char[size];
|
||||
|
||||
fh.read(buf,size);
|
||||
fh.close();
|
||||
|
||||
std::string line,dbname;
|
||||
for(uint32 pos = 0; pos < size; pos++)
|
||||
{
|
||||
if(buf[pos] == '\n')
|
||||
{
|
||||
if(line.empty())
|
||||
continue;
|
||||
while(line[0]==' ' || line[0]=='\t')
|
||||
line.erase(0,1);
|
||||
if(line[0] == '#')
|
||||
{
|
||||
uint32 eq = line.find("=");
|
||||
if(eq != std::string::npos)
|
||||
{
|
||||
std::string info = stringToLower(line.substr(0,pos));
|
||||
std::string value = stringToLower(line.substr(pos+1,line.length()-1));
|
||||
if(info == "#dbname")
|
||||
{
|
||||
dbname = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
line += buf[pos];
|
||||
}
|
||||
delete [] buf;
|
||||
|
||||
if(dbname.empty())
|
||||
return 0;
|
||||
|
||||
uint32 sections = GetDB(dbname).LoadFromMem(buf,size);
|
||||
return sections;
|
||||
|
||||
}
|
||||
|
||||
// -- helper functions -- //
|
||||
|
||||
std::string SCPDatabaseMgr::GetZoneName(uint32 id)
|
||||
std::string SCPDatabaseMgr::GetAreaName(uint32 id)
|
||||
{
|
||||
return GetDB("zone").GetField(id).GetString("name");
|
||||
return GetDB("area").GetField(id).GetString("name");
|
||||
}
|
||||
|
||||
std::string SCPDatabaseMgr::GetRaceName(uint32 id)
|
||||
|
||||
@ -3,21 +3,66 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
struct SCPEntry
|
||||
/*
|
||||
* Some preparations for compiled databases. i will continue this later. [FG]
|
||||
|
||||
enum SCPTypes
|
||||
{
|
||||
std::string entry;
|
||||
std::string value;
|
||||
SCP_TYPE_STRING = 0,
|
||||
SCP_TYPE_INT,
|
||||
SCP_TYPE_UINT,
|
||||
SCP_TYPE_FLOAT
|
||||
};
|
||||
|
||||
class SCPEntry
|
||||
{
|
||||
private:
|
||||
char *str;
|
||||
|
||||
public:
|
||||
|
||||
SCPEntry() { str = NULL; }
|
||||
~SCPEntry() { if(str) delete [] str; }
|
||||
|
||||
union
|
||||
{
|
||||
int32 intvalue
|
||||
uint32 uintvalue;
|
||||
float floatvalue;
|
||||
};
|
||||
|
||||
inline char *GetString(uint8 type)
|
||||
{
|
||||
if(str)
|
||||
return str;
|
||||
else
|
||||
{
|
||||
char buf[25];
|
||||
char *fmt;
|
||||
switch (type)
|
||||
{
|
||||
case SCP_TYPE_INT: sprintf(buf,"%d",intvalue); break;
|
||||
case SCP_TYPE_UINT: sprintf(buf,"%u",uintvalue); break;
|
||||
case SCP_TYPE_FLOAT: sprintf(buf,"%f",floatvalue); break;
|
||||
}
|
||||
str = new char[strlen(buf) + 1];
|
||||
memcpy(str,buf,strlen(buf) + 1);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
typedef std::map<std::string,std::string> SCPEntryMap;
|
||||
|
||||
class SCPField
|
||||
{
|
||||
public:
|
||||
std::string GetString(std::string);
|
||||
uint64 GetInteger(std::string entry) { return toInt(GetString(entry)); }
|
||||
double GetDouble(std::string entry) { return strtod(GetString(entry).c_str(),NULL); }
|
||||
void Set(std::string entry,std::string value) { _map[entry]=value; }
|
||||
inline uint64 GetInteger(std::string entry) { return toInt(GetString(entry)); }
|
||||
inline double GetDouble(std::string entry) { return strtod(GetString(entry).c_str(),NULL); }
|
||||
inline void Set(std::string entry,std::string value) { _map[entry]=value; }
|
||||
bool HasEntry(std::string);
|
||||
|
||||
private:
|
||||
@ -30,9 +75,10 @@ typedef std::map<uint32,SCPField> SCPFieldMap;
|
||||
class SCPDatabase
|
||||
{
|
||||
public:
|
||||
SCPField& GetField(uint32 id) { return _map[id]; }
|
||||
inline SCPField& GetField(uint32 id) { return _map[id]; }
|
||||
bool HasField(uint32 id);
|
||||
uint32 LoadFromFile(char*);
|
||||
uint32 LoadFromMem(char*,uint32);
|
||||
uint32 GetFieldByValue(std::string entry, std::string value);
|
||||
|
||||
private:
|
||||
@ -47,11 +93,13 @@ class SCPDatabaseMgr
|
||||
public:
|
||||
bool HasDB(std::string);
|
||||
SCPDatabase& GetDB(std::string);
|
||||
uint32 AutoLoadFile(char *fn);
|
||||
inline void DropDB(std::string s) { _map.erase(stringToLower(s)); }
|
||||
|
||||
//////////////////////
|
||||
// helper functions //
|
||||
//////////////////////
|
||||
std::string GetZoneName(uint32 id);
|
||||
std::string GetAreaName(uint32 id);
|
||||
std::string GetRaceName(uint32 id);
|
||||
std::string GetClassName_(uint32 id);
|
||||
std::string GetGenderName(uint32 id);
|
||||
|
||||
@ -1,46 +1,66 @@
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "PseuWoW.h"
|
||||
#include "ObjMgr.h"
|
||||
#include "GUI/PseuGUI.h"
|
||||
|
||||
ObjMgr::ObjMgr()
|
||||
{
|
||||
DEBUG(logdebug("DEBUG: ObjMgr created"));
|
||||
}
|
||||
|
||||
ObjMgr::~ObjMgr()
|
||||
{
|
||||
RemoveAll();
|
||||
}
|
||||
|
||||
void ObjMgr::SetInstance(PseuInstance *i)
|
||||
{
|
||||
_instance = i;
|
||||
DEBUG(logdebug("DEBUG: ObjMgr instance set to 0x%X",i));
|
||||
}
|
||||
|
||||
void ObjMgr::RemoveAll(void)
|
||||
{
|
||||
for(ItemProtoList::iterator i = _iproto.begin(); i!=_iproto.end(); i++)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
||||
while(_obj.size())
|
||||
{
|
||||
delete *i;
|
||||
Remove(_obj.begin()->first);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjMgr::Remove(uint64 guid)
|
||||
{
|
||||
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
||||
if((*i)->GetGUID() == guid)
|
||||
Object *o = GetObj(guid);
|
||||
if(o)
|
||||
{
|
||||
delete *i;
|
||||
_obj.erase(i);
|
||||
return;
|
||||
PseuGUI *gui = _instance->GetGUI();
|
||||
if(gui)
|
||||
gui->NotifyObjectDeletion(guid); // we have a gui, which must delete linked DrawObject
|
||||
_obj.erase(guid); // now delete the obj from the mgr
|
||||
delete o; // and delete the obj itself
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ObjMgr::Add(Object *o)
|
||||
{
|
||||
_obj.push_back(o);
|
||||
_obj[o->GetGUID()] = o;
|
||||
|
||||
PseuGUI *gui = _instance->GetGUI();
|
||||
if(gui)
|
||||
gui->NotifyObjectCreation(o);
|
||||
}
|
||||
|
||||
Object *ObjMgr::GetObj(uint64 guid)
|
||||
{
|
||||
if(!guid)
|
||||
return NULL;
|
||||
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
||||
if((*i)->GetGUID() == guid)
|
||||
return (*i);
|
||||
for(ObjectMap::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
||||
if(i->second->GetGUID() == guid)
|
||||
return i->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -7,12 +7,16 @@
|
||||
#include "Item.h"
|
||||
|
||||
typedef std::vector<ItemProto*> ItemProtoList;
|
||||
typedef std::list<Object*> ObjectList;
|
||||
typedef std::map<uint64,Object*> ObjectMap;
|
||||
|
||||
class PseuInstance;
|
||||
|
||||
class ObjMgr
|
||||
{
|
||||
public:
|
||||
ObjMgr();
|
||||
~ObjMgr();
|
||||
void SetInstance(PseuInstance*);
|
||||
void RemoveAll(void); // TODO: this needs to be called on SMSG_LOGOUT_COMPLETE once implemented.
|
||||
|
||||
// Item Prototype functions
|
||||
@ -29,11 +33,13 @@ public:
|
||||
void Add(Object*);
|
||||
void Remove(uint64); // remove all objects with that guid (should be only 1 object in total anyway)
|
||||
Object *GetObj(uint64 guid);
|
||||
inline uint32 GetObjectCount(void) { return _obj.size(); }
|
||||
|
||||
private:
|
||||
ItemProtoList _iproto;
|
||||
ObjectList _obj;
|
||||
ObjectMap _obj;
|
||||
std::vector<uint32> _noitem;
|
||||
PseuInstance *_instance;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -23,9 +23,15 @@ void Player::Create(uint64 guid)
|
||||
|
||||
MyCharacter::MyCharacter() : Player()
|
||||
{
|
||||
DEBUG(logdebug("MyCharacter() constructor, this=0x%x",this));
|
||||
SetTarget(0);
|
||||
}
|
||||
|
||||
MyCharacter::~MyCharacter()
|
||||
{
|
||||
DEBUG(logdebug("~MyCharacter() destructor, this=0x%X guid="I64FMT,this,GetGUID())); // this _could_ crash if Player::Create(guid) wasnt called before!
|
||||
}
|
||||
|
||||
void MyCharacter::SetActionButtons(WorldPacket &data)
|
||||
{
|
||||
|
||||
|
||||
@ -200,6 +200,7 @@ class MyCharacter : public Player
|
||||
{
|
||||
public:
|
||||
MyCharacter();
|
||||
~MyCharacter();
|
||||
|
||||
void SetActionButtons(WorldPacket &data);
|
||||
void AddSpell(uint32 spellid, uint16 spellslot);
|
||||
|
||||
@ -64,8 +64,8 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATETYPE_CREATE_OBJECT:
|
||||
case UPDATETYPE_CREATE_OBJECT2:
|
||||
case UPDATETYPE_CREATE_OBJECT2: // will be sent when our very own character is created
|
||||
case UPDATETYPE_CREATE_OBJECT: // will be sent on any other object creation
|
||||
{
|
||||
uguid = recvPacket.GetPackedGuid();
|
||||
uint8 objtypeid;
|
||||
@ -73,12 +73,22 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
|
||||
logdebug("Create Object type %u with guid "I64FMT,objtypeid,uguid);
|
||||
// dont create objects if already present in memory.
|
||||
// recreate every object except ourself!
|
||||
if( uguid != GetGuid() && objmgr.GetObj(uguid))
|
||||
if(objmgr.GetObj(uguid))
|
||||
{
|
||||
if(uguid != GetGuid())
|
||||
{
|
||||
logdev("- already exists, deleting old , creating new object");
|
||||
objmgr.Remove(uguid);
|
||||
}
|
||||
else
|
||||
{
|
||||
logdev("- already exists, but not deleted (has our current GUID)");
|
||||
}
|
||||
}
|
||||
|
||||
// only if the obj didnt exist or was just deleted above, create it....
|
||||
if(!objmgr.GetObj(uguid))
|
||||
{
|
||||
switch(objtypeid)
|
||||
{
|
||||
case TYPEID_OBJECT: // no data to read
|
||||
@ -135,16 +145,28 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logdebug("Obj "I64FMT" not created, already exists",uguid);
|
||||
}
|
||||
// ...regardless if it was freshly created or already present, update its values and stuff now...
|
||||
this->_MovementUpdate(objtypeid, uguid, recvPacket);
|
||||
this->_ValuesUpdate(uguid, recvPacket);
|
||||
|
||||
// ...and ask the server for eventually missing data.
|
||||
_QueryObjectInfo(uguid);
|
||||
|
||||
// if our own character got finally created, we have successfully entered the world,
|
||||
// and should have gotten all info about our char already.
|
||||
// TODO: make called script function like "_enterworld"
|
||||
//if(uguid==GetGuid())
|
||||
// _OnCharCreate();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case UPDATETYPE_OUT_OF_RANGE_OBJECTS:
|
||||
{
|
||||
recvPacket >> usize;
|
||||
for(uint16 i=0;i<usize;i++)
|
||||
{
|
||||
@ -152,12 +174,15 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket)
|
||||
logdebug("GUID "I64FMT" out of range",uguid);
|
||||
objmgr.Remove(uguid);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
logerror("UPDATE_OBJECT: Got unk updatetype 0x%X",utype);
|
||||
logerror("UPDATE_OBJECT: Read %u / %u bytes, skipped rest",recvPacket.rpos(),recvPacket.size());
|
||||
return;
|
||||
}
|
||||
} // switch
|
||||
} // while
|
||||
|
||||
@ -303,7 +328,7 @@ void WorldSession::_ValuesUpdate(uint64 uguid, WorldPacket& recvPacket)
|
||||
|
||||
obj->SetUInt32Value(i, value);
|
||||
//}
|
||||
// still nee to find out which values to interpret as floats
|
||||
// still need to find out which values to interpret as floats
|
||||
logdev("-> Field[%u] = %u",i,value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ struct OpcodeHandler
|
||||
|
||||
WorldSession::WorldSession(PseuInstance *in)
|
||||
{
|
||||
logdebug("-> Starting WorldSession from instance 0x%X",in); // should never output a null ptr
|
||||
logdebug("-> Starting WorldSession 0x%X from instance 0x%X",this,in); // should never output a null ptr
|
||||
_instance = in;
|
||||
_mustdie=false;
|
||||
_logged=false;
|
||||
@ -31,7 +31,10 @@ WorldSession::WorldSession(PseuInstance *in)
|
||||
_channels = new Channel(this);
|
||||
_world = NULL;
|
||||
_sh.SetAutoCloseSockets(false);
|
||||
objmgr.SetInstance(in);
|
||||
//...
|
||||
|
||||
DEBUG(logdebug("WorldSession 0x%X constructor finished",this));
|
||||
}
|
||||
|
||||
WorldSession::~WorldSession()
|
||||
@ -50,6 +53,7 @@ WorldSession::~WorldSession()
|
||||
delete _socket;
|
||||
if(_world)
|
||||
delete _world;
|
||||
DEBUG(logdebug("~WorldSession() this=0x%X _instance=0x%X",this,_instance));
|
||||
}
|
||||
|
||||
void WorldSession::Start(void)
|
||||
@ -328,8 +332,9 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
GetInstance()->SetError();
|
||||
return;
|
||||
}
|
||||
|
||||
logdetail("Chars in list: %u\n",num);
|
||||
_LoadCache(); // we are about to login, so we need cache data
|
||||
logdetail("W: Chars in list: %u\n",num);
|
||||
for(unsigned int i=0;i<num;i++){
|
||||
recvPacket >> plr[i]._guid;
|
||||
recvPacket >> plr[i]._name;
|
||||
@ -363,13 +368,13 @@ 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; Zone: %s",
|
||||
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().GetZoneName(plr[i]._zoneId).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++)
|
||||
@ -391,7 +396,10 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
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);
|
||||
@ -408,12 +416,18 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
|
||||
void WorldSession::_HandleSetProficiencyOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
_OnEnterWorld();
|
||||
if(recvPacket.size())
|
||||
{
|
||||
DEBUG(
|
||||
logdebug("SetProficiency: Hexdump:");
|
||||
logdebug(toHexDump((uint8*)recvPacket.contents(),recvPacket.size(),true).c_str());
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::_HandleAccountDataMD5Opcode(WorldPacket& recvPacket)
|
||||
{
|
||||
_OnEnterWorld();
|
||||
// packet structure not yet known
|
||||
}
|
||||
|
||||
void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket)
|
||||
@ -438,7 +452,8 @@ void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket)
|
||||
|
||||
recvPacket >> target_guid;
|
||||
std::string plrname;
|
||||
if(target_guid){
|
||||
if(target_guid)
|
||||
{
|
||||
plrname=plrNameCache.GetName(target_guid);
|
||||
if(plrname.empty())
|
||||
{
|
||||
@ -488,7 +503,7 @@ void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket)
|
||||
}
|
||||
else if (type==CHAT_MSG_EMOTE )
|
||||
{
|
||||
logcustom(0,WHITE,"EMOTE: %s [%s]: %s",plrname.c_str(),ln,msg.c_str());
|
||||
logcustom(0,WHITE,"EMOTE [%s]: %s %s",ln,plrname.c_str(),msg.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -560,12 +575,15 @@ void WorldSession::_HandleMessageChatOpcode(WorldPacket& recvPacket)
|
||||
pos++;
|
||||
}
|
||||
id = atoi(itemid.c_str());
|
||||
if(id)
|
||||
{
|
||||
logdebug("Found Item in chat message: %u",id);
|
||||
if(objmgr.GetItemProto(id)==NULL)
|
||||
SendQueryItem(id,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void WorldSession::_HandleNameQueryResponseOpcode(WorldPacket& recvPacket)
|
||||
@ -658,12 +676,14 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket)
|
||||
|
||||
void WorldSession::_HandleNewWorldOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
DEBUG(logdebug("DEBUG: _HandleNewWorldOpcode() objs:%u mychar: ptr=0x%X, guid="I64FMT,objmgr.GetObjectCount(),GetMyChar(),GetMyChar()->GetGUID()));
|
||||
uint32 mapid;
|
||||
float x,y,z,o;
|
||||
// we assume we are NOT on a transport!
|
||||
// else we had to do the following before:
|
||||
// recvPacket >> tmapid >> tx >> ty >> tz >> to;
|
||||
recvPacket >> mapid >> x >> y >> z >> o;
|
||||
if(GetMyChar())
|
||||
GetMyChar()->ClearSpells(); // will be resent by server
|
||||
// TODO: clear action buttons
|
||||
if(_world)
|
||||
@ -857,6 +877,7 @@ void WorldSession::_HandleLoginVerifyWorldOpcode(WorldPacket& recvPacket)
|
||||
recvPacket >> m >> x >> y >> z >> o;
|
||||
// for now, init the world as soon as the server confirmed that we are where we are.
|
||||
logdebug("LoginVerifyWorld: map=%u x=%f y=%f z=%f o=%f",m,x,y,z,o);
|
||||
_OnEnterWorld();
|
||||
if(_world)
|
||||
delete _world;
|
||||
_world = new World(this);
|
||||
|
||||
@ -408,6 +408,18 @@
|
||||
<Filter
|
||||
Name="GUI"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\Client\Gui\DrawObject.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\DrawObject.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\DrawObjMgr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\DrawObjMgr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\PseuGUI.cpp">
|
||||
</File>
|
||||
|
||||
@ -74,12 +74,13 @@ public:
|
||||
inline void SetTile(MapTile* tile, uint32 x, uint32 y) { SetTile(tile, y*64 + x); }
|
||||
inline void SetTile(MapTile* tile, uint32 pos)
|
||||
{
|
||||
if(pos < 4096)
|
||||
_tiles[pos] = tile;
|
||||
}
|
||||
inline void UnloadMapTile(uint32 x, uint32 y) { UnloadMapTile(y*64 + x); }
|
||||
inline void UnloadMapTile(uint32 pos)
|
||||
{
|
||||
if(_tiles[pos])
|
||||
if(pos < 4096 && _tiles[pos])
|
||||
{
|
||||
delete _tiles[pos];
|
||||
_tiles[pos] = NULL;
|
||||
@ -88,12 +89,12 @@ public:
|
||||
inline bool TileExists(uint32 x, uint32 y) { return TileExists(y*64 + x); }
|
||||
inline bool TileExists(uint32 pos)
|
||||
{
|
||||
return _hasTile[pos];
|
||||
return pos < 4096 ? _hasTile[pos] : false;
|
||||
}
|
||||
inline MapTile *GetTile(uint32 x, uint32 y) { return GetTile(y*64 + x); }
|
||||
inline MapTile *GetTile(uint32 pos)
|
||||
{
|
||||
return _tiles[pos];
|
||||
return pos < 4096 ? _tiles[pos] : NULL;
|
||||
}
|
||||
void _DebugDump(void);
|
||||
|
||||
|
||||
@ -130,15 +130,17 @@ std::deque<std::string> GetFileList(std::string path)
|
||||
HANDLE hFil=FindFirstFile(p,&fil);
|
||||
if(hFil!=INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if( !(fil.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
|
||||
files.push_back(std::string(fil.cFileName));
|
||||
while(FindNextFile(hFil,&fil))
|
||||
{
|
||||
if( !(fil.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
|
||||
files.push_back(std::string(fil.cFileName));
|
||||
}
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
while(files.size() && (files.front()=="." || files.front()==".."))
|
||||
files.pop_front();
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user