Protocol updates up to 10.82

This commit is contained in:
TheSumm 2015-10-24 17:46:53 +02:00
parent d9e8bfff4c
commit 0d8791e1a7
12 changed files with 371 additions and 11 deletions

View File

@ -133,6 +133,7 @@ GameSessionKey = 69
GameDeathType = 70
GameIdleAnimations = 71
GameKeepUnawareTiles = 72
GameIngameStore = 73
TextColors = {
red = '#f55e5e', --'#c83200'
@ -216,7 +217,7 @@ CIPSOFT_RSA = "1321277432058722840622950990822933849527763264961655079678763618"
"88792221429527047321331896351555606801473202394175817"
-- set to the latest Tibia.pic signature to make otclient compatible with official tibia
PIC_SIGNATURE = 0x542100C1
PIC_SIGNATURE = 0x557fe565
OsTypes = {
Linux = 1,
@ -280,4 +281,25 @@ DeathType = {
Blessed = 1
}
ProductType = {
Other = 0,
NameChange = 1
}
StoreErrorType = {
NoError = -1,
PurchaseError = 0,
NetworkError = 1,
HistoryError = 2,
TransferError = 3,
Information = 4
}
StoreState = {
None = 0,
New = 1,
Sale = 2,
Timed = 3
}
-- @}

View File

@ -73,7 +73,8 @@ function g_game.getSupportedClients()
1053, 1054, 1055, 1056, 1057,
1058, 1059, 1060, 1061, 1062,
1063, 1064, 1070, 1071, 1072,
1073, 1074, 1075, 1076
1073, 1074, 1075, 1076, 1080,
1081, 1082
}
end

View File

@ -45,11 +45,12 @@ MarketCategory = {
Swords = 20,
WandsRods = 21,
PremiumScrolls = 22,
TibiaCoins = 23,
MetaWeapons = 255
}
MarketCategory.First = MarketCategory.Armors
MarketCategory.Last = MarketCategory.PremiumScrolls
MarketCategory.Last = MarketCategory.TibiaCoins
MarketCategoryWeapons = {
[MarketCategory.Ammunition] = { slots = {255} },
@ -84,6 +85,7 @@ MarketCategoryStrings = {
[20] = 'Swords',
[21] = 'Wands and Rods',
[22] = 'Premium Scrolls',
[23] = 'Tibia Coins',
[255] = 'Weapons'
}

View File

@ -64,7 +64,7 @@ GameServerOpcodes = {
GameServerPlayerSkills = 161,
GameServerPlayerState = 162,
GameServerClearTarget = 163,
GameServerSpellDelay = 164, --870
GameServerSpellDelay = 164, -- 870
GameServerSpellGroupDelay = 165, -- 870
GameServerMultiUseDelay = 166, -- 870
GameServerTalk = 170,
@ -88,8 +88,12 @@ GameServerOpcodes = {
GameServerVipLogout = 212,
GameServerTutorialHint = 220,
GameServerAutomapFlag = 221,
GameServerCoinBalance = 223, -- 1080
GameServerStoreError = 224, -- 1080
GameServerRequestPurchaseData = 225, -- 1080
GameServerQuestLog = 240,
GameServerQuestLine = 241,
GameServerCoinBalanceUpdating = 242, -- 1080
GameServerChannelEvent = 243, -- 910
GameServerItemInfo = 244, -- 910
GameServerPlayerInventory = 245, -- 910
@ -97,7 +101,11 @@ GameServerOpcodes = {
GameServerMarketLeave = 247, -- 944
GameServerMarketDetail = 248, -- 944
GameServerMarketBrowse = 249, -- 944
GameServerShowModalDialog = 250 -- 960
GameServerShowModalDialog = 250, -- 960
GameServerStore = 251, -- 1080
GameServerStoreOffers = 252, -- 1080
GameServerStoreTransactionHistory = 253, -- 1080
GameServerStoreCompletePurchase = 254 -- 1080
}
ClientOpcodes = {
@ -179,6 +187,7 @@ ClientOpcodes = {
ClientBugReport = 230,
ClientRuleViolation = 231,
ClientDebugReport = 232,
ClientTransferCoins = 239, -- 1080
ClientRequestQuestLog = 240,
ClientRequestQuestLine = 241,
ClientNewRuleViolation = 242, -- 910
@ -188,5 +197,10 @@ ClientOpcodes = {
ClientMarketCreate = 246, -- 944
ClientMarketCancel = 247, -- 944
ClientMarketAccept = 248, -- 944
ClientAnswerModalDialog = 249 -- 960
ClientAnswerModalDialog = 249, -- 960
ClientOpenStore = 250, -- 1080
ClientRequestStoreOffers = 251, -- 1080
ClientBuyStoreOffer = 252, -- 1080
ClientOpenTransactionHistory = 253, -- 1080
ClientRequestTransactionHistory = 254 -- 1080
}

View File

@ -404,7 +404,8 @@ namespace Otc
GameSessionKey = 69,
GameDeathType = 70,
GameIdleAnimations = 71,
GameKeepUnawareTiles=72,
GameKeepUnawareTiles = 72,
GameIngameStore = 73,
LastGameFeature = 101
};
@ -474,6 +475,27 @@ namespace Otc
DeathRegular = 0,
DeathBlessed = 1
};
enum StoreProductTypes {
ProductTypeOther = 0,
ProductTypeNameChange = 1
};
enum StoreErrorTypes {
StoreNoError = -1,
StorePurchaseError = 0,
StoreNetworkError = 1,
StoreHistoryError = 2,
StoreTransferError = 3,
StoreInformation = 4
};
enum StoreStates {
StateNone = 0,
StateNew = 1,
StateSale = 2,
StateTimed = 3
};
}
#endif

View File

@ -1395,6 +1395,48 @@ void Game::seekInContainer(int cid, int index)
m_protocolGame->sendSeekInContainer(cid, index);
}
void Game::buyStoreOffer(int offerId, int productType, const std::string& name)
{
if(!canPerformGameAction())
return;
m_protocolGame->sendBuyStoreOffer(offerId, productType, name);
}
void Game::requestTransactionHistory(int page, int entriesPerPage)
{
if(!canPerformGameAction())
return;
m_protocolGame->sendRequestTransactionHistory(page, entriesPerPage);
}
void Game::requestStoreOffers(const std::string& categoryName)
{
if(!canPerformGameAction())
return;
m_protocolGame->sendRequestStoreOffers(categoryName);
}
void Game::openStore()
{
if(!canPerformGameAction())
return;
m_protocolGame->sendOpenStore();
}
void Game::transferCoins(const std::string& recipient, int amount)
{
if(!canPerformGameAction())
return;
m_protocolGame->sendTransferCoins(recipient, amount);
}
void Game::openTransactionHistory(int entriesPerPage)
{
if(!canPerformGameAction())
return;
m_protocolGame->sendOpenTransactionHistory(entriesPerPage);
}
void Game::ping()
{
if(!m_protocolGame || !m_protocolGame->isConnected())
@ -1450,7 +1492,7 @@ void Game::setProtocolVersion(int version)
if(isOnline())
stdext::throw_exception("Unable to change protocol version while online");
if(version != 0 && (version < 740 || version > 1076))
if(version != 0 && (version < 740 || version > 1082))
stdext::throw_exception(stdext::format("Protocol version %d not supported", version));
m_protocolVersion = version;
@ -1468,7 +1510,7 @@ void Game::setClientVersion(int version)
if(isOnline())
stdext::throw_exception("Unable to change client version while online");
if(version != 0 && (version < 740 || version > 1076))
if(version != 0 && (version < 740 || version > 1082))
stdext::throw_exception(stdext::format("Client version %d not supported", version));
m_features.reset();
@ -1620,6 +1662,10 @@ void Game::setClientVersion(int version)
enableFeature(Otc::GameSessionKey);
}
if(version >= 1080) {
enableFeature(Otc::GameIngameStore);
}
m_clientVersion = version;
g_lua.callGlobalField("g_game", "onClientVersionChange", version);

View File

@ -288,6 +288,14 @@ public:
void browseField(const Position& position);
void seekInContainer(int cid, int index);
// >= 1080 ingame store
void buyStoreOffer(int offerId, int productType, const std::string& name = "");
void requestTransactionHistory(int page, int entriesPerPage);
void requestStoreOffers(const std::string& categoryName);
void openStore();
void transferCoins(const std::string& recipient, int amount);
void openTransactionHistory(int entriesPerPage);
//void reportRuleViolation2();
void ping();
void setPingDelay(int delay) { m_pingDelay = delay; }

View File

@ -301,6 +301,12 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_game", "browseField", &Game::browseField, &g_game);
g_lua.bindSingletonFunction("g_game", "seekInContainer", &Game::seekInContainer, &g_game);
g_lua.bindSingletonFunction("g_game", "getLastWalkDir", &Game::getLastWalkDir, &g_game);
g_lua.bindSingletonFunction("g_game", "buyStoreOffer", &Game::buyStoreOffer, &g_game);
g_lua.bindSingletonFunction("g_game", "requestTransactionHistory", &Game::requestTransactionHistory, &g_game);
g_lua.bindSingletonFunction("g_game", "requestStoreOffers", &Game::requestStoreOffers, &g_game);
g_lua.bindSingletonFunction("g_game", "openStore", &Game::openStore, &g_game);
g_lua.bindSingletonFunction("g_game", "transferCoins", &Game::transferCoins, &g_game);
g_lua.bindSingletonFunction("g_game", "openTransactionHistory", &Game::openTransactionHistory, &g_game);
g_lua.registerSingletonClass("g_shaders");
g_lua.bindSingletonFunction("g_shaders", "createShader", &ShaderManager::createShader, &g_shaders);

View File

@ -143,8 +143,12 @@ namespace Proto {
GameServerVipLogout = 212,
GameServerTutorialHint = 220,
GameServerAutomapFlag = 221,
GameServerCoinBalance = 223, // 1080
GameServerStoreError = 224, // 1080
GameServerRequestPurchaseData = 225, // 1080
GameServerQuestLog = 240,
GameServerQuestLine = 241,
GameServerCoinBalanceUpdating = 242, // 1080
GameServerChannelEvent = 243, // 910
GameServerItemInfo = 244, // 910
GameServerPlayerInventory = 245, // 910
@ -152,7 +156,11 @@ namespace Proto {
GameServerMarketLeave = 247, // 944
GameServerMarketDetail = 248, // 944
GameServerMarketBrowse = 249, // 944
GameServerModalDialog = 250 // 960
GameServerModalDialog = 250, // 960
GameServerStore = 251, // 1080
GameServerStoreOffers = 252, // 1080
GameServerStoreTransactionHistory = 253, // 1080
GameServerStoreCompletePurchase = 254 // 1080
};
enum ClientOpcodes : uint8
@ -245,6 +253,7 @@ namespace Proto {
ClientBugReport = 230,
ClientRuleViolation = 231,
ClientDebugReport = 232,
ClientTransferCoins = 239, // 1080
ClientRequestQuestLog = 240,
ClientRequestQuestLine = 241,
ClientNewRuleViolation = 242, // 910
@ -254,7 +263,12 @@ namespace Proto {
ClientMarketCreate = 246, // 944
ClientMarketCancel = 247, // 944
ClientMarketAccept = 248, // 944
ClientAnswerModalDialog = 249 // 960
ClientAnswerModalDialog = 249, // 960
ClientOpenStore = 250, // 1080
ClientRequestStoreOffers = 251, // 1080
ClientBuyStoreOffer = 252, // 1080
ClientOpenTransactionHistory = 253, // 1080
ClientRequestTransactionHistory = 254 // 1080
};
enum CreatureType {

View File

@ -113,6 +113,12 @@ public:
void sendAnswerModalDialog(int dialog, int button, int choice);
void sendBrowseField(const Position& position);
void sendSeekInContainer(int cid, int index);
void sendBuyStoreOffer(int offerId, int productType, const std::string& name);
void sendRequestTransactionHistory(int page, int entriesPerPage);
void sendRequestStoreOffers(const std::string& categoryName);
void sendOpenStore();
void sendTransferCoins(const std::string& recipient, int amount);
void sendOpenTransactionHistory(int entiresPerPage);
// otclient only
void sendChangeMapAwareRange(int xrange, int yrange);
@ -128,6 +134,14 @@ public:
void addPosition(const OutputMessagePtr& msg, const Position& position);
private:
void parseStore(const InputMessagePtr& msg);
void parseStoreError(const InputMessagePtr& msg);
void parseStoreTransactionHistory(const InputMessagePtr& msg);
void parseStoreOffers(const InputMessagePtr& msg);
void parseCompleteStorePurchase(const InputMessagePtr& msg);
void parseRequestPurchaseData(const InputMessagePtr& msg);
void parseCoinBalance(const InputMessagePtr& msg);
void parseCoinBalanceUpdating(const InputMessagePtr& msg);
void parseBlessings(const InputMessagePtr& msg);
void parseUnjustifiedStats(const InputMessagePtr& msg);
void parsePvpSituations(const InputMessagePtr& msg);

View File

@ -356,6 +356,31 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerPreset:
parsePreset(msg);
break;
// PROTOCOL>=1080
case Proto::GameServerCoinBalanceUpdating:
parseCoinBalanceUpdating(msg);
break;
case Proto::GameServerCoinBalance:
parseCoinBalance(msg);
break;
case Proto::GameServerRequestPurchaseData:
parseRequestPurchaseData(msg);
break;
case Proto::GameServerStoreCompletePurchase:
parseCompleteStorePurchase(msg);
break;
case Proto::GameServerStoreOffers:
parseStoreOffers(msg);
break;
case Proto::GameServerStoreTransactionHistory:
parseStoreTransactionHistory(msg);
break;
case Proto::GameServerStoreError:
parseStoreError(msg);
break;
case Proto::GameServerStore:
parseStore(msg);
break;
// otclient ONLY
case Proto::GameServerExtendedOpcode:
parseExtendedOpcode(msg);
@ -396,6 +421,15 @@ void ProtocolGame::parseLogin(const InputMessagePtr& msg)
g_game.setExpertPvpMode(expertModeEnabled);
}
if(g_game.getFeature(Otc::GameIngameStore)) {
// URL to ingame store images
msg->getString();
// premium coin package size
// e.g you can only buy packs of 25, 50, 75, .. coins in the market
msg->getU16();
}
m_localPlayer->setId(playerId);
g_game.setServerBeat(serverBeat);
g_game.setCanReportBugs(canReportBugs);
@ -431,6 +465,124 @@ void ProtocolGame::parsePreset(const InputMessagePtr& msg)
uint16 preset = msg->getU32();
}
void ProtocolGame::parseRequestPurchaseData(const InputMessagePtr& msg)
{
int transactionId = msg->getU32();
int productType = msg->getU8();
}
void ProtocolGame::parseStore(const InputMessagePtr& msg)
{
parseCoinBalance(msg);
// Parse all categories
int count = msg->getU16();
for(int i = 0; i < count; i++) {
std::string category = msg->getString();
std::string description = msg->getString();
std::vector<std::string> icons;
int iconCount = msg->getU8();
for(int i = 0; i < iconCount; i++) {
std::string icon = msg->getString();
icons.push_back(icon);
}
// If this is a valid category name then
// the category we just parsed is a child of that
std::string parentCategory = msg->getString();
}
}
void ProtocolGame::parseCoinBalance(const InputMessagePtr& msg)
{
bool update = msg->getU8() == 1;
int coins = -1;
int transferableCoins = -1;
if(update) {
// amount of coins that can be used to buy prodcuts
// in the ingame store
coins = msg->getU32();
// amount of coins that can be sold in market
// or be transfered to another player
transferableCoins = msg->getU32();
}
}
void ProtocolGame::parseCoinBalanceUpdating(const InputMessagePtr& msg)
{
// coin balance can be updating and might not be accurate
bool isUpdating = msg->getU8() == 1;
}
void ProtocolGame::parseCompleteStorePurchase(const InputMessagePtr& msg)
{
// not used
msg->getU8();
std::string message = msg->getString();
int coins = msg->getU32();
int transferableCoins = msg->getU32();
g_logger.info(stdext::format("Purchase Complete: %s", message));
}
void ProtocolGame::parseStoreTransactionHistory(const InputMessagePtr &msg)
{
int currentPage = msg->getU16();
bool hasNextPage = msg->getU8() == 1;
int entries = msg->getU8();
for(int i = 0; i < entries; i++) {
int time = msg->getU16();
int productType = msg->getU8();
int coinChange = msg->getU32();
std::string productName = msg->getString();
g_logger.error(stdext::format("Time %i, type %i, change %i, product name %s", time, productType, coinChange, productName));
}
}
void ProtocolGame::parseStoreOffers(const InputMessagePtr& msg)
{
std::string categoryName = msg->getString();
int offers = msg->getU16();
for(int i = 0; i < offers; i++) {
int offerId = msg->getU32();
std::string offerName = msg->getString();
std::string offerDescription = msg->getString();
int price = msg->getU32();
int state = msg->getU8();
int disabled = msg->getU8() == 1;
int icons = msg->getU8();
for(int j = 0; j < icons; j++) {
std::string icon = msg->getString();
}
int subOffers = msg->getU16();
for(int j = 0; j < subOffers; j++) {
std::string name = msg->getString();
std::string description = msg->getString();
int subIcons = msg->getU8();
for(int k = 0; k < subIcons; k++) {
std::string icon = msg->getString();
}
std::string serviceType = msg->getString();
}
}
}
void ProtocolGame::parseStoreError(const InputMessagePtr& msg)
{
int errorType = msg->getU8();
std::string message = msg->getString();
g_logger.error(stdext::format("Store Error: %s [%i]", message, errorType));
}
void ProtocolGame::parseUnjustifiedStats(const InputMessagePtr& msg)
{
UnjustifiedPoints unjustifiedPoints;

View File

@ -863,6 +863,65 @@ void ProtocolGame::sendSeekInContainer(int cid, int index)
send(msg);
}
void ProtocolGame::sendBuyStoreOffer(int offerId, int productType, const std::string& name)
{
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientBuyStoreOffer);
msg->addU32(offerId);
msg->addU8(productType);
if(productType == Otc::ProductTypeNameChange)
msg->addString(name);
send(msg);
}
void ProtocolGame::sendRequestTransactionHistory(int page, int entriesPerPage)
{
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestTransactionHistory);
msg->addU16(page);
msg->addU32(entriesPerPage);
send(msg);
}
void ProtocolGame::sendRequestStoreOffers(const std::string& categoryName)
{
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientRequestStoreOffers);
msg->addString(categoryName);
send(msg);
}
void ProtocolGame::sendOpenStore()
{
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientOpenStore);
send(msg);
}
void ProtocolGame::sendTransferCoins(const std::string& recipient, int amount)
{
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientTransferCoins);
msg->addString(recipient);
msg->addU16(amount);
send(msg);
}
void ProtocolGame::sendOpenTransactionHistory(int entriesPerPage)
{
OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientOpenTransactionHistory);
msg->addU8(entriesPerPage);
send(msg);
}
void ProtocolGame::sendChangeMapAwareRange(int xrange, int yrange)
{
if(!g_game.getFeature(Otc::GameChangeMapAwareRange))