Add extended opcode patch for tfs under tools/
This commit is contained in:
parent
91237e82d5
commit
79102f2275
|
@ -131,13 +131,14 @@ void Game::processGameStart()
|
|||
disableBotCall();
|
||||
|
||||
if(g_game.getFeature(Otc::GameClientPing)) {
|
||||
m_protocolGame->sendPing();
|
||||
m_pingEvent = g_dispatcher.cycleEvent([this] {
|
||||
if(m_protocolGame && m_protocolGame->isConnected()) {
|
||||
enableBotCall();
|
||||
m_protocolGame->sendPing();
|
||||
disableBotCall();
|
||||
}
|
||||
}, 1000);
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ private:
|
|||
std::string m_accountName;
|
||||
std::string m_accountPassword;
|
||||
std::string m_characterName;
|
||||
Timer m_pingTimer;
|
||||
stdext::timer m_pingTimer;
|
||||
LocalPlayerPtr m_localPlayer;
|
||||
};
|
||||
|
||||
|
|
|
@ -379,7 +379,7 @@ void ProtocolGame::parsePing(const InputMessagePtr& msg)
|
|||
|
||||
void ProtocolGame::parsePingBack(const InputMessagePtr& msg)
|
||||
{
|
||||
g_game.processPingBack(m_pingTimer.ticksElapsed());
|
||||
g_game.processPingBack(m_pingTimer.elapsed_millis());
|
||||
}
|
||||
|
||||
void ProtocolGame::parseChallange(const InputMessagePtr& msg)
|
||||
|
@ -1379,7 +1379,7 @@ void ProtocolGame::parseExtendedOpcode(const InputMessagePtr& msg)
|
|||
if(opcode == 0)
|
||||
m_enableSendExtendedOpcode = true;
|
||||
else
|
||||
callLuaField("onExtendedOpcode", opcode, buffer);
|
||||
callLuaField("onExtendedOpcode", opcode, buffer);
|
||||
}
|
||||
|
||||
void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height)
|
||||
|
|
|
@ -0,0 +1,396 @@
|
|||
diff --git a/const.h b/const.h
|
||||
index cd479e4..8d46b23 100644
|
||||
--- a/const.h
|
||||
+++ b/const.h
|
||||
@@ -21,9 +21,12 @@
|
||||
|
||||
enum OperatingSystem_t
|
||||
{
|
||||
- CLIENTOS_LINUX = 0x01,
|
||||
- CLIENTOS_WINDOWS = 0x02,
|
||||
- CLIENTOS_FLASH = 0x03
|
||||
+ CLIENTOS_LINUX = 0x01,
|
||||
+ CLIENTOS_WINDOWS = 0x02,
|
||||
+ CLIENTOS_FLASH = 0x03,
|
||||
+ CLIENTOS_OTCLIENT_LINUX = 0x0A,
|
||||
+ CLIENTOS_OTCLIENT_WINDOWS = 0x0B,
|
||||
+ CLIENTOS_OTCLIENT_MAC = 0x0C,
|
||||
};
|
||||
|
||||
enum ChannelEvent_t
|
||||
diff --git a/creatureevent.cpp b/creatureevent.cpp
|
||||
index 842b237..e9b2200 100644
|
||||
--- a/creatureevent.cpp
|
||||
+++ b/creatureevent.cpp
|
||||
@@ -211,6 +211,8 @@ CreatureEventType_t CreatureEvents::getType(const std::string& type)
|
||||
_type = CREATURE_EVENT_DEATH;
|
||||
else if(type == "preparedeath")
|
||||
_type = CREATURE_EVENT_PREPAREDEATH;
|
||||
+ else if(type == "extendedopcode")
|
||||
+ _type = CREATURE_EVENT_EXTENDED_OPCODE;
|
||||
|
||||
return _type;
|
||||
}
|
||||
@@ -330,6 +332,8 @@ std::string CreatureEvent::getScriptEventName() const
|
||||
return "onDeath";
|
||||
case CREATURE_EVENT_PREPAREDEATH:
|
||||
return "onPrepareDeath";
|
||||
+ case CREATURE_EVENT_EXTENDED_OPCODE:
|
||||
+ return "onExtendedOpcode";
|
||||
case CREATURE_EVENT_NONE:
|
||||
default:
|
||||
break;
|
||||
@@ -401,6 +405,8 @@ std::string CreatureEvent::getScriptEventParams() const
|
||||
return "cid, corpse, deathList";
|
||||
case CREATURE_EVENT_PREPAREDEATH:
|
||||
return "cid, deathList";
|
||||
+ case CREATURE_EVENT_EXTENDED_OPCODE:
|
||||
+ return "cid, opcode, buffer";
|
||||
case CREATURE_EVENT_NONE:
|
||||
default:
|
||||
break;
|
||||
@@ -2145,3 +2151,57 @@ uint32_t CreatureEvent::executeAction(Creature* creature, Creature* target)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+
|
||||
+uint32_t CreatureEvent::executeExtendedOpcode(Creature* creature, uint8_t opcode, const std::string& buffer)
|
||||
+{
|
||||
+ //onExtendedOpcode(cid, opcode, buffer)
|
||||
+ if(m_interface->reserveEnv())
|
||||
+ {
|
||||
+ ScriptEnviroment* env = m_interface->getEnv();
|
||||
+ if(m_scripted == EVENT_SCRIPT_BUFFER)
|
||||
+ {
|
||||
+ env->setRealPos(creature->getPosition());
|
||||
+ std::stringstream scriptstream;
|
||||
+ scriptstream << "local cid = " << env->addThing(creature) << std::endl;
|
||||
+ scriptstream << "local opcode = " << (int)opcode << std::endl;
|
||||
+ scriptstream << "local buffer = " << buffer.c_str() << std::endl;
|
||||
+
|
||||
+ scriptstream << m_scriptData;
|
||||
+ bool result = true;
|
||||
+ if(m_interface->loadBuffer(scriptstream.str()))
|
||||
+ {
|
||||
+ lua_State* L = m_interface->getState();
|
||||
+ result = m_interface->getGlobalBool(L, "_result", true);
|
||||
+ }
|
||||
+
|
||||
+ m_interface->releaseEnv();
|
||||
+ return result;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ #ifdef __DEBUG_LUASCRIPTS__
|
||||
+ char desc[35];
|
||||
+ sprintf(desc, "%s", player->getName().c_str());
|
||||
+ env->setEvent(desc);
|
||||
+ #endif
|
||||
+
|
||||
+ env->setScriptId(m_scriptId, m_interface);
|
||||
+ env->setRealPos(creature->getPosition());
|
||||
+
|
||||
+ lua_State* L = m_interface->getState();
|
||||
+ m_interface->pushFunction(m_scriptId);
|
||||
+ lua_pushnumber(L, env->addThing(creature));
|
||||
+ lua_pushnumber(L, opcode);
|
||||
+ lua_pushlstring(L, buffer.c_str(), buffer.length());
|
||||
+
|
||||
+ bool result = m_interface->callFunction(3);
|
||||
+ m_interface->releaseEnv();
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ std::cout << "[Error - CreatureEvent::executeRemoved] Call stack overflow." << std::endl;
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/creatureevent.h b/creatureevent.h
|
||||
index f1ff4b2..cc5171c 100644
|
||||
--- a/creatureevent.h
|
||||
+++ b/creatureevent.h
|
||||
@@ -57,7 +57,8 @@ enum CreatureEventType_t
|
||||
CREATURE_EVENT_CAST,
|
||||
CREATURE_EVENT_KILL,
|
||||
CREATURE_EVENT_DEATH,
|
||||
- CREATURE_EVENT_PREPAREDEATH
|
||||
+ CREATURE_EVENT_PREPAREDEATH,
|
||||
+ CREATURE_EVENT_EXTENDED_OPCODE // otclient additional network opcodes
|
||||
};
|
||||
|
||||
enum StatsChange_t
|
||||
@@ -150,6 +151,7 @@ class CreatureEvent : public Event
|
||||
uint32_t executeKill(Creature* creature, Creature* target, const DeathEntry& entry);
|
||||
uint32_t executeDeath(Creature* creature, Item* corpse, DeathList deathList);
|
||||
uint32_t executePrepareDeath(Creature* creature, DeathList deathList);
|
||||
+ uint32_t executeExtendedOpcode(Creature* creature, uint8_t opcode, const std::string& buffer);
|
||||
//
|
||||
|
||||
protected:
|
||||
diff --git a/data/creaturescripts/creaturescripts.xml b/data/creaturescripts/creaturescripts.xml
|
||||
index 363c62b..c706f10 100644
|
||||
--- a/data/creaturescripts/creaturescripts.xml
|
||||
+++ b/data/creaturescripts/creaturescripts.xml
|
||||
@@ -14,4 +14,6 @@
|
||||
|
||||
<event type="think" name="Idle" event="script" value="idle.lua"/>
|
||||
<event type="think" name="SkullCheck" event="script" value="skullcheck.lua"/>
|
||||
+
|
||||
+ <event type="extendedopcode" name="ExtendedOpcode" event="script" value="extendedopcode.lua"/>
|
||||
</creaturescripts>
|
||||
diff --git a/game.cpp b/game.cpp
|
||||
index 2e4dc2c..7508591 100644
|
||||
--- a/game.cpp
|
||||
+++ b/game.cpp
|
||||
@@ -6951,3 +6951,12 @@ void Game::checkExpiredMarketOffers()
|
||||
|
||||
Scheduler::getInstance().addEvent(createSchedulerTask(checkExpiredMarketOffersEachMinutes * 60 * 1000, boost::bind(&Game::checkExpiredMarketOffers, this)));
|
||||
}
|
||||
+
|
||||
+void Game::parsePlayerExtendedOpcode(Player *player, uint8_t opcode, const std::string& buffer)
|
||||
+{
|
||||
+ if(player) {
|
||||
+ CreatureEventList extendedOpcodeEvents = player->getCreatureEvents(CREATURE_EVENT_EXTENDED_OPCODE);
|
||||
+ for(CreatureEventList::iterator it = extendedOpcodeEvents.begin(); it != extendedOpcodeEvents.end(); ++it)
|
||||
+ (*it)->executeExtendedOpcode(player, opcode, buffer);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/game.h b/game.h
|
||||
index 51fa397..7192549 100644
|
||||
--- a/game.h
|
||||
+++ b/game.h
|
||||
@@ -646,6 +646,8 @@ class Game
|
||||
std::map<Item*, int32_t> grounds;
|
||||
#endif
|
||||
|
||||
+ void parsePlayerExtendedOpcode(Player *player, uint8_t opcode, const std::string& buffer);
|
||||
+
|
||||
protected:
|
||||
bool playerWhisper(Player* player, const std::string& text, uint32_t statementId);
|
||||
bool playerYell(Player* player, const std::string& text, uint32_t statementId);
|
||||
diff --git a/luascript.cpp b/luascript.cpp
|
||||
index 4cb8c8d..4ed9391 100644
|
||||
--- a/luascript.cpp
|
||||
+++ b/luascript.cpp
|
||||
@@ -2476,6 +2476,12 @@ void LuaInterface::registerFunctions()
|
||||
//getConfigFile()
|
||||
lua_register(m_luaState, "getConfigFile", LuaInterface::luaGetConfigFile);
|
||||
|
||||
+ //isPlayerUsingOtclient(cid)
|
||||
+ lua_register(m_luaState, "isPlayerUsingOtclient", LuaInterface::luaIsPlayerUsingOtclient);
|
||||
+
|
||||
+ //doSendPlayerExtendedOpcode(cid, opcode, buffer)
|
||||
+ lua_register(m_luaState, "doSendPlayerExtendedOpcode", LuaInterface::luaDoSendPlayerExtendedOpcode);
|
||||
+
|
||||
//getConfigValue(key)
|
||||
lua_register(m_luaState, "getConfigValue", LuaInterface::luaGetConfigValue);
|
||||
|
||||
@@ -9471,6 +9477,32 @@ int32_t LuaInterface::luaGetMountInfo(lua_State* L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+int32_t LuaInterface::luaIsPlayerUsingOtclient(lua_State* L)
|
||||
+{
|
||||
+ //isPlayerUsingOtclient(cid)
|
||||
+ ScriptEnviroment* env = getEnv();
|
||||
+ if(Player* player = env->getPlayerByUID(popNumber(L))) {
|
||||
+ lua_pushboolean(L, player->isUsingOtclient());
|
||||
+ }
|
||||
+ lua_pushboolean(L, false);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int32_t LuaInterface::luaDoSendPlayerExtendedOpcode(lua_State* L)
|
||||
+{
|
||||
+ //doSendPlayerExtendedOpcode(cid, opcode, buffer)
|
||||
+ std::string buffer = popString(L);
|
||||
+ int opcode = popNumber(L);
|
||||
+
|
||||
+ ScriptEnviroment* env = getEnv();
|
||||
+ if(Player* player = env->getPlayerByUID(popNumber(L))) {
|
||||
+ player->sendExtendedOpcode(opcode, buffer);
|
||||
+ lua_pushboolean(L, true);
|
||||
+ }
|
||||
+ lua_pushboolean(L, false);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
int32_t LuaInterface::luaGetPartyMembers(lua_State* L)
|
||||
{
|
||||
//getPartyMembers(cid)
|
||||
diff --git a/luascript.h b/luascript.h
|
||||
index 234091a..0a0046f 100644
|
||||
--- a/luascript.h
|
||||
+++ b/luascript.h
|
||||
@@ -697,6 +697,9 @@ class LuaInterface
|
||||
static int32_t luaDoPlayerSetMounted(lua_State* L);
|
||||
static int32_t luaGetMountInfo(lua_State* L);
|
||||
|
||||
+ static int32_t luaIsPlayerUsingOtclient(lua_State* L);
|
||||
+ static int32_t luaDoSendPlayerExtendedOpcode(lua_State* L);
|
||||
+
|
||||
static int32_t luaL_errors(lua_State* L);
|
||||
static int32_t luaL_loadmodlib(lua_State* L);
|
||||
static int32_t luaL_domodlib(lua_State* L);
|
||||
diff --git a/networkmessage.cpp b/networkmessage.cpp
|
||||
index 917e36a..3671750 100644
|
||||
--- a/networkmessage.cpp
|
||||
+++ b/networkmessage.cpp
|
||||
@@ -171,16 +171,16 @@ Position NetworkMessage::getPosition()
|
||||
return pos;
|
||||
}
|
||||
|
||||
-void NetworkMessage::putString(const char* value, bool addSize/* = true*/)
|
||||
+void NetworkMessage::putString(const char* value, int length, bool addSize/* = true*/)
|
||||
{
|
||||
- uint32_t size = (uint32_t)strlen(value);
|
||||
+ uint32_t size = (uint32_t)length;
|
||||
if(!hasSpace(size + (addSize ? 2 : 0)) || size > 8192)
|
||||
return;
|
||||
|
||||
if(addSize)
|
||||
put<uint16_t>(size);
|
||||
|
||||
- strcpy((char*)(m_buffer + m_position), value);
|
||||
+ memcpy((char*)(m_buffer + m_position), value, length);
|
||||
m_position += size;
|
||||
m_size += size;
|
||||
}
|
||||
diff --git a/networkmessage.h b/networkmessage.h
|
||||
index 6cf8ee1..615f094 100644
|
||||
--- a/networkmessage.h
|
||||
+++ b/networkmessage.h
|
||||
@@ -80,8 +80,8 @@ class NetworkMessage
|
||||
m_size += sizeof(T);
|
||||
}
|
||||
|
||||
- void putString(const std::string& value, bool addSize = true) {putString(value.c_str(), addSize);}
|
||||
- void putString(const char* value, bool addSize = true);
|
||||
+ void putString(const std::string& value, bool addSize = true) {putString(value.c_str(), value.length(), addSize);}
|
||||
+ void putString(const char* value, int length, bool addSize = true);
|
||||
|
||||
void putPadding(uint32_t amount);
|
||||
|
||||
diff --git a/player.h b/player.h
|
||||
index 63e9183..e003e63 100644
|
||||
--- a/player.h
|
||||
+++ b/player.h
|
||||
@@ -228,6 +228,7 @@ class Player : public Creature, public Cylinder
|
||||
bool hasPVPBlessing() const {return pvpBlessing;}
|
||||
uint16_t getBlessings() const;
|
||||
|
||||
+ bool isUsingOtclient() const { return operatingSystem >= CLIENTOS_OTCLIENT_LINUX; }
|
||||
OperatingSystem_t getOperatingSystem() const {return operatingSystem;}
|
||||
void setOperatingSystem(OperatingSystem_t os) {operatingSystem = os;}
|
||||
uint32_t getClientVersion() const {return clientVersion;}
|
||||
@@ -400,7 +401,7 @@ class Player : public Creature, public Cylinder
|
||||
onSell = saleCallback;
|
||||
return shopOwner;
|
||||
}
|
||||
-
|
||||
+
|
||||
//Quest functions
|
||||
void onUpdateQuest();
|
||||
|
||||
@@ -580,6 +581,9 @@ class Player : public Creature, public Cylinder
|
||||
void sendSpellGroupCooldown(SpellGroup_t groupId, uint32_t cooldown)
|
||||
{if(client) client->sendSpellGroupCooldown(groupId, cooldown);}
|
||||
|
||||
+ void sendExtendedOpcode(uint8_t opcode, const std::string& buffer)
|
||||
+ {if(client) client->sendExtendedOpcode(opcode, buffer);}
|
||||
+
|
||||
//container
|
||||
void sendAddContainerItem(const Container* container, const Item* item);
|
||||
void sendUpdateContainerItem(const Container* container, uint8_t slot, const Item* oldItem, const Item* newItem);
|
||||
diff --git a/protocolgame.cpp b/protocolgame.cpp
|
||||
index b980be0..c75654e 100644
|
||||
--- a/protocolgame.cpp
|
||||
+++ b/protocolgame.cpp
|
||||
@@ -263,6 +263,11 @@ bool ProtocolGame::login(const std::string& name, uint32_t id, const std::string
|
||||
return false;
|
||||
}
|
||||
|
||||
+ if(player->isUsingOtclient())
|
||||
+ {
|
||||
+ player->registerCreatureEvent("ExtendedOpcode");
|
||||
+ }
|
||||
+
|
||||
player->lastIP = player->getIP();
|
||||
player->lastLoad = OTSYS_TIME();
|
||||
player->lastLogin = std::max(time(NULL), player->lastLogin + 1);
|
||||
@@ -427,6 +432,10 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg)
|
||||
enableXTEAEncryption();
|
||||
setXTEAKey(key);
|
||||
|
||||
+ // notifies to otclient that this server can receive extended game protocol opcodes
|
||||
+ if(operatingSystem >= CLIENTOS_OTCLIENT_LINUX)
|
||||
+ sendExtendedOpcode(0x00, std::string());
|
||||
+
|
||||
bool gamemaster = (msg.get<char>() != (char)0);
|
||||
std::string name = msg.getString(), character = msg.getString(), password = msg.getString();
|
||||
|
||||
@@ -578,6 +587,10 @@ void ProtocolGame::parsePacket(NetworkMessage &msg)
|
||||
parseReceivePing(msg);
|
||||
break;
|
||||
|
||||
+ case 0x32: // otclient extended opcode
|
||||
+ parseExtendedOpcode(msg);
|
||||
+ break;
|
||||
+
|
||||
case 0x64: // move with steps
|
||||
parseAutoWalk(msg);
|
||||
break;
|
||||
@@ -2411,7 +2424,7 @@ void ProtocolGame::sendMarketDetail(uint16_t itemId)
|
||||
}
|
||||
else
|
||||
msg->put<char>(0x00);
|
||||
-
|
||||
+
|
||||
if((statistics = IOMarket::getInstance()->getSaleStatistics(itemId)))
|
||||
{
|
||||
msg->put<char>(0x01);
|
||||
@@ -3705,3 +3718,28 @@ void ProtocolGame::AddShopItem(NetworkMessage_ptr msg, const ShopInfo& item)
|
||||
msg->put<uint32_t>(item.buyPrice);
|
||||
msg->put<uint32_t>(item.sellPrice);
|
||||
}
|
||||
+
|
||||
+void ProtocolGame::parseExtendedOpcode(NetworkMessage& msg)
|
||||
+{
|
||||
+ uint8_t opcode = msg.get<char>();
|
||||
+ std::string buffer = msg.getString();
|
||||
+
|
||||
+ // process additional opcodes via lua script event
|
||||
+ addGameTask(&Game::parsePlayerExtendedOpcode, player, opcode, buffer);
|
||||
+}
|
||||
+
|
||||
+void ProtocolGame::sendExtendedOpcode(uint8_t opcode, const std::string& buffer)
|
||||
+{
|
||||
+ // extended opcodes can only be send to players using otclient, cipsoft's tibia can't understand them
|
||||
+ if(player && !player->isUsingOtclient())
|
||||
+ return;
|
||||
+
|
||||
+ NetworkMessage_ptr msg = getOutputBuffer();
|
||||
+ if(msg)
|
||||
+ {
|
||||
+ TRACK_MESSAGE(msg);
|
||||
+ msg->put<char>(0x32);
|
||||
+ msg->put<char>(opcode);
|
||||
+ msg->putString(buffer);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/protocolgame.h b/protocolgame.h
|
||||
index 7691174..48b9bf1 100644
|
||||
--- a/protocolgame.h
|
||||
+++ b/protocolgame.h
|
||||
@@ -326,6 +326,9 @@ class ProtocolGame : public Protocol
|
||||
//shop
|
||||
void AddShopItem(NetworkMessage_ptr msg, const ShopInfo& item);
|
||||
|
||||
+ void parseExtendedOpcode(NetworkMessage& msg);
|
||||
+ void sendExtendedOpcode(uint8_t opcode, const std::string& buffer);
|
||||
+
|
||||
#define addGameTask(f, ...) addGameTaskInternal(0, boost::bind(f, &g_game, __VA_ARGS__))
|
||||
#define addGameTaskTimed(delay, f, ...) addGameTaskInternal(delay, boost::bind(f, &g_game, __VA_ARGS__))
|
||||
template<class FunctionType>
|
Loading…
Reference in New Issue