This commit is contained in:
OTCv8 2020-07-16 16:59:46 +02:00
parent 760162d581
commit a65844f182
12 changed files with 543 additions and 355 deletions

View File

@ -303,9 +303,9 @@ function CharacterList.create(characters, account, otui)
status = tr(' (Suspended)')
end
if account.subStatus == SubscriptionStatus.Free then
if account.subStatus == SubscriptionStatus.Free and account.premDays < 1 then
accountStatusLabel:setText(('%s%s'):format(tr('Free Account'), status))
elseif account.subStatus == SubscriptionStatus.Premium then
else
if account.premDays == 0 or account.premDays == 65535 then
accountStatusLabel:setText(('%s%s'):format(tr('Gratis Premium Account'), status))
else

View File

@ -166,6 +166,16 @@ local function onTibia12HTTPResult(session, playdata)
end
end
-- proxies
if g_proxy then
g_proxy.clear()
if playdata["proxies"] then
for i, proxy in ipairs(playdata["proxies"]) do
g_proxy.addProxy(proxy["host"], tonumber(proxy["port"]), tonumber(proxy["priority"]))
end
end
end
g_game.setCustomProtocolVersion(0)
g_game.chooseRsa(G.host)
g_game.setClientVersion(G.clientVersion)
@ -414,7 +424,7 @@ function EnterGame.doLogin()
G.host = server_params[1] .. ":" .. server_params[2] .. ":" .. server_params[3]
G.clientVersion = tonumber(server_params[4])
elseif #server_params >= 3 then
if tonumber(server_params[3]) == server_params[3] then
if tostring(tonumber(server_params[3])) == server_params[3] then
G.host = server_params[1] .. ":" .. server_params[2]
G.clientVersion = tonumber(server_params[3])
end

View File

@ -1,19 +1,6 @@
function init()
-- add manually your shaders from /data/shaders
g_shaders.createOutfitShader("default", "/shaders/outfit_default_vertex", "/shaders/outfit_default_fragment")
--[[ g_shaders.createOutfitShader("stars", "/shaders/outfit_stars_vertex", "/shaders/outfit_stars_fragment")
g_shaders.addTexture("stars", "/shaders/stars.png")
g_shaders.createOutfitShader("gold", "/shaders/outfit_gold_vertex", "/shaders/outfit_gold_fragment")
g_shaders.addTexture("gold", "/data/shaders/gold.png")
g_shaders.createOutfitShader("rainbow", "/shaders/outfit_rainbow_vertex", "/shaders/outfit_rainbow_fragment")
g_shaders.addTexture("rainbow", "/shaders/rainbow.png")
g_shaders.createOutfitShader("line", "/shaders/outfit_line_vertex", "/shaders/outfit_line_fragment")
g_shaders.createOutfitShader("outline", "/shaders/outfit_outline_vertex", "/shaders/outfit_outline_fragment") ]]--
end
function terminate()

View File

@ -486,7 +486,11 @@ function changeCategory(widget, newCategory)
end
if g_game.getFeature(GameIngameStore) and widget ~= newCategory and not otcv8shop then
g_game.requestStoreOffers(newCategory.name:getText())
local serviceType = 0
if g_game.getFeature(GameTibia12Protocol) then
serviceType = 2
end
g_game.requestStoreOffers(newCategory.name:getText(), serviceType)
end
browsingHistory = false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -56,6 +56,8 @@ namespace Proto {
GameServerPing = 30,
GameServerChallenge = 31,
GameServerDeath = 40,
GameServerSupplyStash = 41,
GameServerDepotState = 42,
// all in game opcodes must be greater than 50
GameServerFirstGameOpcode = 50,
@ -125,7 +127,8 @@ namespace Proto {
GameServerEditText = 150,
GameServerEditList = 151,
GameServerNews = 152,
GameServerSendBlessDialog = 155,
GameUnkown154 = 154,
GameServerBlessDialog = 155,
GameServerBlessings = 156,
GameServerPreset = 157,
GameServerPremiumTrigger = 158, // 1038
@ -157,6 +160,8 @@ namespace Proto {
GameServerPvpSituations = 184,
GameServerFloorChangeUp = 190,
GameServerFloorChangeDown = 191,
GameServerLootContainers = 192,
GameServerTournamentLeaderboard = 197,
GameServerChooseOutfit = 200,
GameServerImpactTracker = 204,
GameServerItemsPrices = 205,
@ -166,10 +171,10 @@ namespace Proto {
GameServerKillTracker = 209,
GameServerVipAdd = 210,
GameServerVipState = 211,
GameServerVipLogout = 212,
GameServerVipLogoutOrGroupData = 212,
GameServerCyclopediaNewDetails = 217,
GameServerTutorialHint = 220,
GameServerAutomapFlag = 221,
GameServerCyclopediaMapData = 221,
GameServerDailyRewardState = 222,
GameServerCoinBalance = 223,
GameServerStoreError = 224, // 1080
@ -183,7 +188,7 @@ namespace Proto {
GameServerPreyPrices = 233,
GameServerStoreOfferDescription = 234,
GameServerImbuementWindow = 235,
GaneServerCloseImbuementWindow = 236,
GameServerCloseImbuementWindow = 236,
GameServerMessageDialog = 237,
GameServerResourceBalance = 238,
GameServerTime = 239,

View File

@ -251,8 +251,9 @@ private:
void parseVipAdd(const InputMessagePtr& msg);
void parseVipState(const InputMessagePtr& msg);
void parseVipLogout(const InputMessagePtr& msg);
void parseVipGroupData(const InputMessagePtr& msg);
void parseTutorialHint(const InputMessagePtr& msg);
void parseAutomapFlag(const InputMessagePtr& msg);
void parseCyclopediaMapData(const InputMessagePtr& msg);
void parseQuestLog(const InputMessagePtr& msg);
void parseQuestLine(const InputMessagePtr& msg);
void parseChannelEvent(const InputMessagePtr& msg);
@ -274,7 +275,11 @@ private:
void parseDailyReward(const InputMessagePtr& msg);
void parseDailyRewardHistory(const InputMessagePtr& msg);
void parseKillTracker(const InputMessagePtr& msg);
void parseLootContainers(const InputMessagePtr& msg);
void parseSupplyStash(const InputMessagePtr& msg);
void parseDepotState(const InputMessagePtr& msg);
void parseSupplyTracker(const InputMessagePtr& msg);
void parseTournamentLeaderboard(const InputMessagePtr& msg);
void parseImpactTracker(const InputMessagePtr& msg);
void parseItemsPrices(const InputMessagePtr& msg);
void parseLootTracker(const InputMessagePtr& msg);

View File

@ -305,14 +305,17 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerVipState:
parseVipState(msg);
break;
case Proto::GameServerVipLogout:
case Proto::GameServerVipLogoutOrGroupData:
if (g_game.getFeature(Otc::GameTibia12Protocol))
parseVipGroupData(msg);
else
parseVipLogout(msg);
break;
case Proto::GameServerTutorialHint:
parseTutorialHint(msg);
break;
case Proto::GameServerAutomapFlag:
parseAutomapFlag(msg);
case Proto::GameServerCyclopediaMapData:
parseCyclopediaMapData(msg);
break;
case Proto::GameServerQuestLog:
parseQuestLog(msg);
@ -420,6 +423,8 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerNews:
parseGameNews(msg);
break;
case Proto::GameUnkown154: // spotted on skelot
break;
case Proto::GameServerBlessDialog:
parseBlessDialog(msg);
break;
@ -486,6 +491,18 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerDailyRewardHistory:
parseDailyRewardHistory(msg);
break;
case Proto::GameServerLootContainers:
parseLootContainers(msg);
break;
case Proto::GameServerSupplyStash:
parseSupplyStash(msg);
break;
case Proto::GameServerDepotState:
parseDepotState(msg);
break;
case Proto::GameServerTournamentLeaderboard:
parseTournamentLeaderboard(msg);
break;
// otclient ONLY
case Proto::GameServerExtendedOpcode:
parseExtendedOpcode(msg);
@ -529,14 +546,14 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
}
} catch (stdext::exception& e) {
g_logger.error(stdext::format("ProtocolGame parse message exception (%d bytes, %d unread, last opcode is 0x%02x (%d), prev opcode is 0x%02x (%d)): %s"
"\nPacket has been saved to packet.log, you can use it to find what was wrong.",
msg->getMessageSize(), msg->getUnreadSize(), opcode, opcode, prevOpcode, prevOpcode, e.what()));
"\nPacket has been saved to packet.log, you can use it to find what was wrong. (Protocol: %i)",
msg->getMessageSize(), msg->getUnreadSize(), opcode, opcode, prevOpcode, prevOpcode, e.what(), g_game.getProtocolVersion()));
std::ofstream packet("packet.log", std::ifstream::app);
if (!packet.is_open())
return;
packet << stdext::format("ProtocolGame parse message exception (%d bytes, %d unread, last opcode is 0x%02x (%d), prev opcode is 0x%02x (%d)): %s\n",
msg->getMessageSize(), msg->getUnreadSize(), opcode, opcode, prevOpcode, prevOpcode, e.what());
packet << stdext::format("ProtocolGame parse message exception (%d bytes, %d unread, last opcode is 0x%02x (%d), prev opcode is 0x%02x (%d), proto: %i): %s\n",
msg->getMessageSize(), msg->getUnreadSize(), opcode, opcode, prevOpcode, prevOpcode, g_game.getProtocolVersion(), e.what());
std::string buffer = msg->getBuffer();
opcodePos -= msg->getHeaderPos();
prevOpcodePos -= msg->getHeaderPos();
@ -1410,10 +1427,14 @@ void ProtocolGame::parseMagicEffect(const InputMessagePtr& msg)
if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getClientVersion() >= 1203) {
Otc::MagicEffectsType_t effectType = (Otc::MagicEffectsType_t)msg->getU8();
while (effectType != Otc::MAGIC_EFFECTS_END_LOOP) {
if (effectType == Otc::MAGIC_EFFECTS_CREATE_DISTANCEEFFECT) {
if (effectType == Otc::MAGIC_EFFECTS_DELTA) {
msg->getU8();
} else if (effectType == Otc::MAGIC_EFFECTS_DELAY) {
msg->getU8(); // ?
} else if (effectType == Otc::MAGIC_EFFECTS_CREATE_DISTANCEEFFECT) {
uint8_t shotId = msg->getU8();
uint8_t offsetX = msg->getU8();
uint8_t offsetY = msg->getU8();
int8_t offsetX = static_cast<int8_t>(msg->getU8());
int8_t offsetY = static_cast<int8_t>(msg->getU8());
if (!g_things.isValidDatId(shotId, ThingCategoryMissile)) {
g_logger.traceError(stdext::format("invalid missile id %d", shotId));
return;
@ -1423,6 +1444,19 @@ void ProtocolGame::parseMagicEffect(const InputMessagePtr& msg)
missile->setId(shotId);
missile->setPath(pos, Position(pos.x + offsetX, pos.y + offsetY, pos.z));
g_map.addThing(missile, pos);
} else if (effectType == Otc::MAGIC_EFFECTS_CREATE_DISTANCEEFFECT_REVERSED) {
uint8_t shotId = msg->getU8();
int8_t offsetX = static_cast<int8_t>(msg->getU8());
int8_t offsetY = static_cast<int8_t>(msg->getU8());
if (!g_things.isValidDatId(shotId, ThingCategoryMissile)) {
g_logger.traceError(stdext::format("invalid missile id %d", shotId));
return;
}
MissilePtr missile = MissilePtr(new Missile());
missile->setId(shotId);
missile->setPath(Position(pos.x + offsetX, pos.y + offsetY, pos.z), pos);
g_map.addThing(missile, pos);
} else if (effectType == Otc::MAGIC_EFFECTS_CREATE_EFFECT) {
uint8_t effectId = msg->getU8();
if (!g_things.isValidDatId(effectId, ThingCategoryEffect)) {
@ -1814,7 +1848,7 @@ void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg)
else
freeCapacity = msg->getU16() / 100.0;
double totalCapacity = 0;
double totalCapacity = freeCapacity;
if (g_game.getFeature(Otc::GameTotalCapacity) && !g_game.getFeature(Otc::GameTibia12Protocol))
totalCapacity = msg->getU32() / 100.0;
@ -1837,8 +1871,9 @@ void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg)
/*double experienceBonus = */msg->getDouble();
} else {
/*int baseXpGain = */msg->getU16();
if(!g_game.getFeature(Otc::GameTibia12Protocol))
if (!g_game.getFeature(Otc::GameTibia12Protocol)) {
/*int voucherAddend = */msg->getU16();
}
/*int grindingAddend = */msg->getU16();
/*int storeBoostAddend = */ msg->getU16();
/*int huntingBoostFactor = */ msg->getU16();
@ -2188,21 +2223,24 @@ void ProtocolGame::parseTextMessage(const InputMessagePtr& msg)
std::string text;
switch (mode) {
case Otc::MessageChannelManagement: {
case Otc::MessageChannelManagement:
{
/*int channel = */msg->getU16();
text = msg->getString();
break;
}
case Otc::MessageGuild:
case Otc::MessagePartyManagement:
case Otc::MessageParty: {
case Otc::MessageParty:
{
/*int channel = */msg->getU16();
text = msg->getString();
break;
}
case Otc::MessageDamageDealed:
case Otc::MessageDamageReceived:
case Otc::MessageDamageOthers: {
case Otc::MessageDamageOthers:
{
Position pos = getPosition(msg);
uint value[2];
int color[2];
@ -2230,7 +2268,8 @@ void ProtocolGame::parseTextMessage(const InputMessagePtr& msg)
case Otc::MessageMana:
case Otc::MessageExp:
case Otc::MessageHealOthers:
case Otc::MessageExpOthers: {
case Otc::MessageExpOthers:
{
Position pos = getPosition(msg);
uint value = msg->getU32();
int color = msg->getU8();
@ -2310,8 +2349,7 @@ void ProtocolGame::parseFloorChangeDown(const InputMessagePtr& msg)
int j, i;
for (i = pos.z, j = -1; i <= pos.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE; ++i, --j)
skip = setFloorDescription(msg, pos.x - range.left, pos.y - range.top, i, range.horizontal(), range.vertical(), j, skip);
}
else if(pos.z > Otc::UNDERGROUND_FLOOR && pos.z < Otc::MAX_Z-1)
} else if (pos.z > Otc::UNDERGROUND_FLOOR && pos.z < Otc::MAX_Z - 1)
skip = setFloorDescription(msg, pos.x - range.left, pos.y - range.top, pos.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE, range.horizontal(), range.vertical(), -3, skip);
}
@ -2415,6 +2453,12 @@ void ProtocolGame::parseVipAdd(const InputMessagePtr& msg)
}
status = msg->getU8();
if (g_game.getFeature(Otc::GameTibia12Protocol)) {
int groups = msg->getU8();
for (int i = 0; i < groups; ++i)
msg->getU8(); // group id
}
g_game.processVipAdd(id, name, status, desc, iconId, notifyLogin);
}
@ -2424,8 +2468,7 @@ void ProtocolGame::parseVipState(const InputMessagePtr& msg)
if (g_game.getFeature(Otc::GameLoginPending)) {
uint status = msg->getU8();
g_game.processVipStateChange(id, status);
}
else {
} else {
g_game.processVipStateChange(id, 1);
}
}
@ -2436,16 +2479,117 @@ void ProtocolGame::parseVipLogout(const InputMessagePtr& msg)
g_game.processVipStateChange(id, 0);
}
void ProtocolGame::parseVipGroupData(const InputMessagePtr& msg)
{
int size = msg->getU8();
for (int i = 0; i < size; ++i) {
msg->getU8(); // group id
msg->getString(); // group name
msg->getU8(); // unkown
}
msg->getU8(); // max vip groups
}
void ProtocolGame::parseTutorialHint(const InputMessagePtr& msg)
{
int id = msg->getU8();
g_game.processTutorialHint(id);
}
void ProtocolGame::parseAutomapFlag(const InputMessagePtr& msg)
void ProtocolGame::parseCyclopediaMapData(const InputMessagePtr& msg)
{
if (g_game.getFeature(Otc::GameTibia12Protocol)) {
msg->getU8(); // unknown
int type = msg->getU8();
switch (type) {
case 0:
break;
case 1:
{
int count = msg->getU16();
for (int i = 0; i < count; ++i) {
msg->getU8();
msg->getU8();
msg->getU8();
msg->getU8();
}
count = msg->getU16();
for (int i = 0; i < count; ++i) {
msg->getU16();
}
count = msg->getU16();
for (int i = 0; i < count; ++i) {
msg->getU16();
}
break;
}
case 2: // raid
{
getPosition(msg);
msg->getU8();
break;
}
case 3:
{
msg->getU8();
msg->getU8();
msg->getU8();
break;
}
case 4:
{
msg->getU8();
msg->getU8();
msg->getU8();
break;
}
case 5:
{
msg->getU16();
msg->getU8();
int count = msg->getU8();
for (int i = 0; i < count; ++i) {
getPosition(msg);
msg->getU8();
}
break;
}
case 6:
{
break;
}
case 7:
{
break;
}
case 8:
{
break;
}
case 9:
{
msg->getU32();
msg->getU32();
int count = msg->getU8();
for (int i = 0; i < count; ++i) {
msg->getU16();
msg->getU32();
msg->getU32();
msg->getU8();
}
}
case 10:
{
msg->getU16();
break;
}
case 11:
{
break;
}
}
if (type != 0)
return;
}
Position pos = getPosition(msg);
@ -2554,8 +2698,7 @@ void ProtocolGame::parseModalDialog(const InputMessagePtr& msg)
if (g_game.getClientVersion() > 970) {
escapeButton = msg->getU8();
enterButton = msg->getU8();
}
else {
} else {
enterButton = msg->getU8();
escapeButton = msg->getU8();
}
@ -2745,6 +2888,39 @@ Imbuement ProtocolGame::getImbuementInfo(const InputMessagePtr& msg)
return i;
}
void ProtocolGame::parseLootContainers(const InputMessagePtr& msg)
{
msg->getU8(); // quickLootFallbackToMainContainer ? 1 : 0
int containers = msg->getU8();
for (int i = 0; i < containers; ++i) {
msg->getU8(); // id?
msg->getU16();
}
}
void ProtocolGame::parseSupplyStash(const InputMessagePtr& msg)
{
int size = msg->getU16();
for (int i = 0; i < size; ++i) {
msg->getU16(); // item id
msg->getU32(); // unknown
}
msg->getU16(); // available slots?
}
void ProtocolGame::parseDepotState(const InputMessagePtr& msg)
{
msg->getU8(); // unknown, true/false
if (g_game.getProtocolVersion() >= 1230) {
msg->getU8(); // unknown
}
}
void ProtocolGame::parseTournamentLeaderboard(const InputMessagePtr& msg)
{
msg->getU8();
msg->getU8();
}
void ProtocolGame::parseKillTracker(const InputMessagePtr& msg)
{
@ -2861,6 +3037,9 @@ void ProtocolGame::parseCreatureType(const InputMessagePtr& msg)
uint32 id = msg->getU32();
uint8 type = msg->getU8();
if (g_game.getFeature(Otc::GameTibia12Protocol) && type == Proto::CreatureTypeSummonOwn)
msg->getU32();
CreaturePtr creature = g_map.getCreatureById(id);
if (creature)
creature->setType(type);
@ -2910,8 +3089,7 @@ void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, i
startz = z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE;
endz = std::min<int>(z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::MAX_Z);
zstep = 1;
}
else {
} else {
startz = Otc::SEA_FLOOR;
endz = 0;
zstep = -1;
@ -2999,14 +3177,12 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg, bool ignoreMount)
outfit.setLegs(legs);
outfit.setFeet(feet);
outfit.setAddons(addons);
}
else {
} else {
int lookTypeEx = msg->getU16();
if (lookTypeEx == 0) {
outfit.setCategory(ThingCategoryEffect);
outfit.setAuxId(13); // invisible effect id
}
else {
} else {
if (!g_things.isValidDatId(lookTypeEx, ThingCategoryItem)) {
g_logger.traceError(stdext::format("invalid outfit looktypeex %d", lookTypeEx));
lookTypeEx = 0;
@ -3120,8 +3296,7 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
creature = m_localPlayer;
else
creature = PlayerPtr(new Player);
}
else if (creatureType == Proto::CreatureTypeMonster)
} else if (creatureType == Proto::CreatureTypeMonster)
creature = MonsterPtr(new Monster);
else if (creatureType == Proto::CreatureTypeNpc)
creature = NpcPtr(new Npc);
@ -3162,11 +3337,13 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
if (g_game.getFeature(Otc::GameThingMarks)) {
creatureType = msg->getU8();
if (g_game.getFeature(Otc::GameTibia12Protocol)) {
if (creatureType == Proto::CreatureTypeSummonOwn)
msg->getU32(); // master
if (g_game.getClientVersion() >= 1220 && creatureType == Proto::CreatureTypePlayer)
msg->getU8(); // vocation id
}
}
if (g_game.getFeature(Otc::GameCreatureIcons)) {
icon = msg->getU8();