diff --git a/bin/data/scp/zone.scp b/bin/data/scp/zone.scp deleted file mode 100644 index ff322a1..0000000 --- a/bin/data/scp/zone.scp +++ /dev/null @@ -1,130 +0,0 @@ -[0] -name=Azeroth - -[1] -name=Kalimdor - -[2] -name=UnderMine - -[13] -name=Test zone - -[17] -name=Kalidar - -[30] -name=Alterac Valley - -[33] -name=Shadowfang Keep Instance - -[34] -name=The Stockade Instance - -[35] -name=Stormwind Prizon - -[36] -name=Deadmines Instance - -[37] -name=Plains of Snow - -[43] -name=Wailing Caverns Instance -[44] -name=Monastery Interior - -[47] -name=Razorfen Kraul Instance - -[48] -name=Blackfathom Deeps Instance - -[70] -name=Uldaman Instance - -[90] -name=Gnomeregan Instance - -[109] -name=Sunken Temple Instance - -[129] -name=Razorfen Downs Instance - -[150] -name=Outland - -[169] -name=Emerald Forest - -[189] -name=Scarlet Monastery Instance - -[209] -name=Zul'Farrak Instance - -[229] -name=Blackrock Spire Instance - -[230] -name=Blackrock Depths Instance - -[249] -name=Onyxia's Lair Instance - -[269] -name=Caverns of Time - -[289] -name=Scholomance Instance - -[309] -name=Zul'Gurub Instance - -[329] -name=Stratholme Instance - -[349] -name=Mauradon Instance - -[369] -name=Deeprun Tram - -[389] -name=Ragefire Chasm Instance - -[409] -name=The Molten Core Instance - -[429] -name=Dire Maul Instance - -[449] -name=Alliance PVP Barracks - -[450] -name=Horde PVP Barracks - -[451] -name=Development Land - -[469] -name=Blackwing Lair Instance - -[489] -name=Warsong Gulch - -[509] -name=Ruins of Ahn'Qiraj Instance - -[529] -name=Arathi Basin - -[531] -name=Temple of Ahn'Qiraj Instance - -[533] -name=Naxxramas Instance diff --git a/src/Client/GUI/PseuGUI.cpp b/src/Client/GUI/PseuGUI.cpp index c223182..26cb14f 100644 --- a/src/Client/GUI/PseuGUI.cpp +++ b/src/Client/GUI/PseuGUI.cpp @@ -93,8 +93,23 @@ void PseuGUI::UseShadows(bool b) void PseuGUI::_Init(void) { _device = createDevice(_driverType,dimension2d(_xres,_yres),_colordepth,!_windowed,_shadows,_vsync); + if(!_device) + { + logerror("PseuGUI: Can't use specified video driver, trying software mode..."); + _device = createDevice(video::EDT_SOFTWARE,dimension2d(_xres,_yres),_colordepth,!_windowed,false,false); + if(!_device) + { + logerror("ERROR: PseuGUI::_Init() failed, no video driver available!"); + return; + } + else + { + logerror("PseuGUI: Software mode OK!"); + } + } DEBUG(logdebug("PseuGUI::Init() _device=%X",_device)); _device->setWindowCaption(L"PseuWoW - Initializing"); + _device->setResizeAble(true); _driver = _device->getVideoDriver(); _smgr = _device->getSceneManager(); _guienv = _device->getGUIEnvironment(); @@ -130,6 +145,12 @@ void PseuGUI::Run(void) { if(!_initialized) this->_Init(); + if(!_initialized) // recheck + { + logerror("PseuGUI: not initialized, using non-GUI mode"); + Cancel(); + return; + } DEBUG(logdebug("PseuGUI::Run() _device=%X",_device)); @@ -137,6 +158,8 @@ void PseuGUI::Run(void) while(_device && _device->run() && !_mustdie) { + // _HandleWindowResize(); // not yet used; doesnt work + if (!_device->isWindowActive()) { _device->sleep(10); // save cpu & gpu power if not focused @@ -225,7 +248,7 @@ void PseuGUI::_UpdateSceneState(void) } } -void PseuGUI::DrawCurrentScene() +void PseuGUI::DrawCurrentScene(void) { if(!_initialized) return; @@ -233,3 +256,25 @@ void PseuGUI::DrawCurrentScene() _scene->Draw(); } +void PseuGUI::_HandleWindowResize(void) +{ + dimension2d scrn = _driver->getScreenSize(); + if(_screendimension.Width != scrn.Width) + { + scrn.Height = s32(scrn.Width * 0.8f); // for now use aspect ratio 5:4 + _screendimension = scrn; + _driver->OnResize(scrn); + DEBUG(logdebug("DEBUG: Width resize handled, Height adjusted")); + + } + else if(_screendimension.Height != scrn.Height) + { + scrn.Width = s32(scrn.Height * 1.25); // 5:4 here too + _screendimension = scrn; + _driver->OnResize(scrn); + DEBUG(logdebug("DEBUG: Height resize handled, Width adjusted")); + + } + // TODO: how to set irrlicht window size ?! + +} diff --git a/src/Client/GUI/PseuGUI.h b/src/Client/GUI/PseuGUI.h index 5ea49e2..ffc1b57 100644 --- a/src/Client/GUI/PseuGUI.h +++ b/src/Client/GUI/PseuGUI.h @@ -77,6 +77,7 @@ public: private: void _Init(void); void _UpdateSceneState(void); + void _HandleWindowResize(void); uint16 _xres,_yres,_colordepth; bool _windowed,_vsync,_shadows; bool _initialized,_mustdie; @@ -89,6 +90,7 @@ private: PseuInstance *_instance; SceneState _scenestate, _scenestate_new; Scene *_scene; + irr::core::dimension2d _screendimension; }; diff --git a/src/Client/SCPDatabase.cpp b/src/Client/SCPDatabase.cpp index 309bac3..55be06a 100644 --- a/src/Client/SCPDatabase.cpp +++ b/src/Client/SCPDatabase.cpp @@ -170,9 +170,9 @@ uint32 SCPDatabaseMgr::AutoLoadFile(char *fn) // -- helper functions -- // -std::string SCPDatabaseMgr::GetAreaName(uint32 id) +std::string SCPDatabaseMgr::GetZoneName(uint32 id) { - return GetDB("area").GetField(id).GetString("name"); + return GetDB("zone").GetField(id).GetString("name"); } std::string SCPDatabaseMgr::GetRaceName(uint32 id) diff --git a/src/Client/SCPDatabase.h b/src/Client/SCPDatabase.h index c7da857..f27c119 100644 --- a/src/Client/SCPDatabase.h +++ b/src/Client/SCPDatabase.h @@ -99,7 +99,7 @@ public: ////////////////////// // helper functions // ////////////////////// - std::string GetAreaName(uint32 id); + std::string GetZoneName(uint32 id); std::string GetRaceName(uint32 id); std::string GetClassName_(uint32 id); std::string GetGenderName(uint32 id); diff --git a/src/Client/World/CMSGConstructor.cpp b/src/Client/World/CMSGConstructor.cpp index bc682e0..573feaa 100644 --- a/src/Client/World/CMSGConstructor.cpp +++ b/src/Client/World/CMSGConstructor.cpp @@ -146,5 +146,35 @@ void WorldSession::SendCastSpell(uint32 spellid, bool nocheck) logerror(" - WARNING: spell is NOT known!"); } +void WorldSession::SendWhoListRequest(uint32 minlvl, uint32 maxlvl, uint32 racemask, uint32 classmask, std::string name, std::string guildname, std::vector *zonelist, std::vector *strlist) +{ + WorldPacket pkt(CMSG_WHO, 50); // guess size + pkt << minlvl; + pkt << maxlvl; + pkt << name; + pkt << guildname; + pkt << racemask; + pkt << classmask; + + if(zonelist) + { + pkt << (uint32)zonelist->size(); + for(uint32 i = 0; i < zonelist->size(); i++) + pkt << (*zonelist)[i]; + } + else + pkt << uint32(0); + + if(strlist) + { + pkt << (uint32)strlist->size(); + for(uint32 i = 0; i < strlist->size(); i++) + pkt << (*strlist)[i]; + } + else + pkt << uint32(0); +} + + diff --git a/src/Client/World/CacheHandler.cpp b/src/Client/World/CacheHandler.cpp index 4568aa3..fc6a10b 100644 --- a/src/Client/World/CacheHandler.cpp +++ b/src/Client/World/CacheHandler.cpp @@ -101,11 +101,16 @@ bool PlayerNameCache::ReadFromFile(void) bool success=true; std::fstream fh; fh.open(fn, std::ios_base::in | std::ios_base::binary); - if(!fh) + if(!fh.is_open()) { logerror("PlayerNameCache: Could not open file '%s'!",fn); return false; } + if(fh.eof()) + { + logdetail("PlayerNameCache: Can't load empty file '%s'",fn); + return false; + } uint32 size; fh.read((char*)&size,sizeof(uint32)); std::string tmp; diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index b4e982e..3e589ab 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -235,6 +235,7 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const {SMSG_LOGIN_VERIFY_WORLD, &WorldSession::_HandleLoginVerifyWorldOpcode}, {SMSG_MOTD, &WorldSession::_HandleMotdOpcode}, {SMSG_NOTIFICATION, &WorldSession::_HandleNotificationOpcode}, + {SMSG_WHO, &WorldSession::_HandleWhoOpcode}, // table termination { 0, NULL } @@ -386,13 +387,13 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) for(unsigned int i=0;i 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++) @@ -552,7 +553,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,"http://my.opera.com/PseuWoW",""); + SendChatMessage(CHAT_MSG_SAY,lang,"www.mangosclient.org",""); 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",""); } @@ -940,6 +941,59 @@ void WorldSession::_HandleLoginVerifyWorldOpcode(WorldPacket& recvPacket) _world->UpdatePos(x,y,m); } +ByteBuffer& operator>>(ByteBuffer& bb, WhoListEntry& e) +{ + bb >> e.name >> e.level >> e.classId >> e.raceId, e.zoneId; + return bb; +} + +void WorldSession::_HandleWhoOpcode(WorldPacket& recvPacket) +{ + uint32 count, unk; + recvPacket >> count >> unk; + + log("Got WHO-List, %u players. (unk=%u)",count,unk); + WhoListEntry wle; + + if(count >= 1) + { + log(" Name |Level| Class | Race | Zone"); + log("--------------+-----+----------+----------+----------------"); + if(count > 1) + { + _whoList.clear(); // need to clear current list only if requesting more then one player name + } + } + + for(uint32 i = 0; i < count; i++) + { + recvPacket >> wle; + + _whoList.push_back(wle); + + // original WhoListEntry is saved, now do some formatting + while(wle.name.length() < 12) + wle.name += ' '; + + SCPDatabaseMgr& db = GetInstance()->dbmgr; + std::string zonename = db.GetZoneName(wle.zoneId); + std::string classname = db.GetClassName_(wle.classId); + std::string racename = db.GetRaceName(wle.raceId); + + while(classname.length() < 8) + classname += ' '; + while(racename.length() < 8) + racename += ' '; + char tmp[12]; + sprintf(tmp,"%u",wle.level); + std::string lvl_str = tmp; + while(lvl_str.length() < 3) + lvl_str = " " + lvl_str; + + log("%s | %s | %s | %s | %s", wle.name.c_str(), lvl_str.c_str(), classname.c_str(), racename.c_str(), zonename.c_str() ); + } +} + // TODO: delete world on LogoutComplete once implemented diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index aa9bf88..4ba7eac 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -17,6 +17,16 @@ class RealmSession; struct OpcodeHandler; class World; +struct WhoListEntry +{ + std::string name; + uint32 level; + uint32 classId; + uint32 raceId; + uint32 zoneId; +}; + +typedef std::vector WhoList; class WorldSession { @@ -45,13 +55,15 @@ public: // CMSGConstructor - void SendChatMessage(uint32 type, uint32 lang, std::string msg, std::string to); + void SendChatMessage(uint32 type, uint32 lang, std::string msg, std::string to=""); void SendQueryPlayerName(uint64 guid); void SendPing(uint32); void SendEmote(uint32); void SendQueryItem(uint32, uint64); void SendSetSelection(uint64); void SendCastSpell(uint32 spellid, bool nocheck=false); + void SendWhoListRequest(uint32 minlvl=0, uint32 maxlvl=100, uint32 racemask=-1, uint32 classmask=-1, std::string name="", std::string guildname="", std::vector *zonelist=NULL, std::vector *strlist=NULL); + PlayerNameCache plrNameCache; ObjMgr objmgr; @@ -93,6 +105,7 @@ private: void _HandleLoginVerifyWorldOpcode(WorldPacket& recvPacket); void _HandleMotdOpcode(WorldPacket& recvPacket); void _HandleNotificationOpcode(WorldPacket& recvPacket); + void _HandleWhoOpcode(WorldPacket& recvPacket); // helper functions to keep SMSG_(COMPRESSED_)UPDATE_OBJECT easy to handle void _MovementUpdate(uint8 objtypeid, uint64 guid, WorldPacket& recvPacket); // Helper for _HandleUpdateObjectOpcode @@ -109,6 +122,7 @@ private: Channel *_channels; uint64 _myGUID; World *_world; + WhoList _whoList; }; #endif \ No newline at end of file