Ir para conteúdo
  • Cadastre-se

11.x [WIP] OTXServer 12.31 Global Full + Kilmaresh (Issavi) + BESTIARY - QUICKLOOT


Posts Recomendados

9 minutos atrás, Jaurez disse:

@malucooo Testei aqui o tibia coins no market, ele não pode ser colocado a venda, apenas cria oferta para comprar, mesmo assim só cria a oferta colocando o valor de "1 gp" e a quantidade fica em 1500.

Dá uma olhada nas fotos:

  Ocultar conteúdo

Criar oferta para venda fica assim e não cria.

58d2a6b9b2aab_Semttulo.thumb.png.6023f2eceecdb1c8c35823423e7ddcfe.png

Criar oferta para compra apenas 1gp e fica como se quisesse comprar 1500 itens

58d2a6bedc134_Semttulo2.thumb.png.968f4e7f7b637dc5a65efe5338c95b4d.png

Tentar criar oferta de compra com mais de 1gp

58d2a6c40d28f_Semttulo3.thumb.png.b07f93191c7b25b9e7154dcbadacda94.png

 

devo ter errado ou esquecido algo na hora de adicionar

 

 

 

O melhor conteúdo da atualidade!

http://www.gitlab.com/malucooo/otxserver-new/

- Full Global Map with 12.xx updates, all quests and many features!

- Protocol 12.31

Link para o post
Compartilhar em outros sites
  • Respostas 5k
  • Created
  • Última resposta

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

OTXServer Global Full Kilmaresh by Malucooo   [CLIENTS COMPATÍVEIS]   http://www.gitlab.com/guilhermesidney/cliente10/   [DOWNLOAD] BAIXEM EM: https://github.com/malucooo

Adicionado Imbuing System, Inspection System por Charles (Eternal-Scripts) Corrigido e atualizado Prey System por Charles (Eternal-Scripts)   Obrigado pela colaboração, acredito que no

Atualizações de Médio Porte:   - Items.otb 11.31 (adicionado os novos barris de potion e mais uns 700 items adicionado..) - Client 10 Atualizado - Adicionado a categoria carpet...

Posted Images

2 horas atrás, malucooo disse:

devo ter errado ou esquecido algo na hora de adicionar

 

o problema de 1500 é na config.lua, tem que mudar coinPacketSize: 1500 para 25

Pra quem quiser um site 100% funcional, eu peguei um gesior e dei uma futucada nele, não está na versão final ainda, pois estou sem tempo pra trabalhar com OT, mas quem quiser me ajudar no projeto eu posso mandar meu htdocs

CONHEÇA MEU PROJETO:

WWW.ETERNUS-GLOBAL.COM

 

tibia-logo.gif

Link para o post
Compartilhar em outros sites
Em 20/03/2017 ás 14:07, malucooo disse:

Com muita falta de paciencia e humildade adicionei ao git as sources com o walkfield e adicionei uma distro com o tibia coins no market, gostaria que testassem!

Por Favor! recapitulem aqui abaixo os bugs encontrados para que eu vá removendo... erros primários serão encaminhados para área de tutoriais!

fixado no github!

bug dos frags segue as print :

 

1º  print matei 2x e nao apareceu frags   "!frags"

2º print matei 3x peguei red !frags  30 unjustified kills         30 dias red Skull       Na  config.lua    timeToDecreaseFrags = 24* 60 * 60 * 1000   dayKillsToRedSkull = 30

3º print matei 3x peguei red  !frags 48 unjustified kills         2 dias red     Na  config .lua  timeToDecreaseFrags = 1* 60 * 60 * 1000     dayKillsToRedSkull = 2

4º e 5º  Site esta Invertido As Morte Conta Como Frags !

 

 

1.png

2.png

3.png

4.png

5.png

 

@malucooo

Editado por Lukiinhaaa (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
4 minutos atrás, kk4444 disse:
  Ocultar conteúdo

 

O 4° print está certo, que são as últimas mortes do server.

Sim Eu Sei So Postei Pra Ver q Char Test Morreu as 5x  

Link para o post
Compartilhar em outros sites
5 hours ago, Rockersz said:

o problema de 1500 é na config.lua, tem que mudar coinPacketSize: 1500 para 25

Pra quem quiser um site 100% funcional, eu peguei um gesior e dei uma futucada nele, não está na versão final ainda, pois estou sem tempo pra trabalhar com OT, mas quem quiser me ajudar no projeto eu posso mandar meu htdocs

 

Poste para nós para que eu possa ver como está seu HTDOCS

>>>>>>>>ĞФĐ βθŋ™<<<<<<<<
Você que é meu fan use minha bar

godbon.png
zeldagodbon.png

Link para o post
Compartilhar em outros sites
Em 17/3/2017 ás 12:42, malucooo disse:

great! but i don't have the modifications, a friend from otland give the distro for tests, but not work too... show ur modifications and we can put this to working =]~ srry for bad english

@darkjav where are u man?

 

Hi bro, what you need? :D

Link para o post
Compartilhar em outros sites

 Em alguns locais o Orc Berserker esta como npc, principalmente na Orc Fortress...
 Caso alguem esteja com o mesmo, eu usei notepad++ e abri o arquivo \data\world\global-spawn.xml
 usei a função para substituir todos os <npc name="Orc Berserker" por <monster name="Orc Berserker".

Link para o post
Compartilhar em outros sites
Em 17/3/2017 ás 12:26, Streamside disse:

@malucooo

hello there malucoo, im Streamside from otland, I got a pretty decent walkable field AI but its not working as cipsoft does.
I already forked your project but can't find your modifications on the walkable behaviour.
I can show you my part to keep your project growing.

 

Hi bro, open a commit in https://github.com/otxserver-new/master/

and so i can check and work together for release!

Thanks!

Link para o post
Compartilhar em outros sites

NPC Cledwyn não está completo, ele fala o nome dos itens para trocar mas alguns quando você pede estão faltando...
adicionei os que estavam faltando no seu script, troque o código abaixo pelo existente em \data\npc\scripts\Cledwyn.lua:

Spoiler

 local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
 
function onCreatureAppear(cid)    npcHandler:onCreatureAppear(cid)   end
function onCreatureDisappear(cid)   npcHandler:onCreatureDisappear(cid)   end
function onCreatureSay(cid, type, msg)   npcHandler:onCreatureSay(cid, type, msg)  end
function onThink()     npcHandler:onThink()     end
 
local items = {
          item1 = {25172, 25178}, --earthheart hauberk
          item2 = {25172, 25177}, --earthheart cuirass
          item3 = {25172, 25179}, --earthheart platemail
          item4 = {25172, 25191}, --earthmind raiment           
          item5 = {25172, 25187}, --earthsoul tabard
          
          item6 = {25172, 25174}, --fireheart cuirass
          item7 = {25172, 25175}, --fireheart hauberk
          item8 = {25172, 25176}, --fireheart platemail
          item9 = {25172, 25190}, --firemind raiment          
          item10 = {25172, 25186}, --firesoul tabard
          
          item11 = {25172, 25183}, --frostheart cuirass
          item12 = {25172, 25184}, --frostheart hauberk
          item13 = {25172, 25185}, --frostheart platemail
          item14 = {25172, 25189}, --frostsoul tabard          
          item15 = {25172, 25193}, --frostmind raiment
          
          item16 = {25172, 25180}, --thunderheart cuirass
          item17 = {25172, 25181}, --thunderheart hauberk
          item18 = {25172, 25182}, --thunderheart platemail
          item19 = {25172, 25192}, --thundermind raiment
          item20 = {25172, 25188} --thundersoul tabard
         
}
local counts = {
          count1 = {100, 1}, -- count1 quantidade que será pedido e que será dado na primeira troca
          count2 = {100, 1}, -- count2 quantidade que será pedido e que será dado na segunda troca
          count3 = {100, 1}, 
          count4 = {100, 1}, 
          count5 = {100, 1},
          count6 = {100, 1},
          count7 = {100, 1}, 
          count8 = {100, 1},
          count9 = {100, 1},  
          count10 = {100, 1},
          count11 = {100, 1},
          count12 = {100, 1}, 
          count13 = {100, 1}, 
          count14 = {100, 1}, 
          count15 = {100, 1},
          count16 = {100, 1},
          count17 = {100, 1},
          count18 = {100, 1},
          count19 = {100, 1},
          count20 = {100, 1}
         
}
 
function creatureSayCallback(cid, type, msg)
          if(not npcHandler:isFocused(cid)) then
                    return false
          end
          local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid

          if  msgcontains(msg, 'earthheart cuirass') then
                    if getPlayerItemCount(cid, items.item2[1]) >= counts.count2[1] then
                              doPlayerRemoveItem(cid, items.item2[1], counts.count2[1])
                              doPlayerAddItem(cid, items.item2[2], counts.count2[2])
                              selfSay('You just swap '.. counts.count2[1] ..' '.. getItemName(items.item2[1]) ..' for '.. counts.count2[2] ..' '.. getItemName(items.item2[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count2[1] ..' '.. getItemName(items.item2[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'earthheart platemail') then
                    if getPlayerItemCount(cid, items.item3[1]) >= counts.count3[1] then
                              doPlayerRemoveItem(cid, items.item3[1], counts.count3[1])
                              doPlayerAddItem(cid, items.item3[2], counts.count3[2])
                              selfSay('You just swap '.. counts.count3[1] ..' '.. getItemName(items.item3[1]) ..' for '.. counts.count3[2] ..' '.. getItemName(items.item3[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count3[1] ..' '.. getItemName(items.item3[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'earthmind raiment') then
                    if getPlayerItemCount(cid, items.item4[1]) >= counts.count4[1] then
                              doPlayerRemoveItem(cid, items.item4[1], counts.count4[1])
                              doPlayerAddItem(cid, items.item4[2], counts.count4[2])
                              selfSay('You just swap '.. counts.count4[1] ..' '.. getItemName(items.item4[1]) ..' for '.. counts.count4[2] ..' '.. getItemName(items.item4[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count4[1] ..' '.. getItemName(items.item4[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'earthsoul tabard') then
                    if getPlayerItemCount(cid, items.item5[1]) >= counts.count5[1] then
                              doPlayerRemoveItem(cid, items.item5[1], counts.count5[1])
                              doPlayerAddItem(cid, items.item5[2], counts.count5[2])
                              selfSay('You just swap '.. counts.count5[1] ..' '.. getItemName(items.item5[1]) ..' for '.. counts.count5[2] ..' '.. getItemName(items.item5[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count5[1] ..' '.. getItemName(items.item5[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'fireheart cuirass') then
                    if getPlayerItemCount(cid, items.item6[1]) >= counts.count6[1] then
                              doPlayerRemoveItem(cid, items.item6[1], counts.count6[1])
                              doPlayerAddItem(cid, items.item6[2], counts.count6[2])
                              selfSay('You just swap '.. counts.count6[1] ..' '.. getItemName(items.item6[1]) ..' for '.. counts.count6[2] ..' '.. getItemName(items.item6[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count6[1] ..' '.. getItemName(items.item6[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'fireheart hauberk') then
                    if getPlayerItemCount(cid, items.item7[1]) >= counts.count7[1] then
                              doPlayerRemoveItem(cid, items.item7[1], counts.count7[1])
                              doPlayerAddItem(cid, items.item7[2], counts.count7[2])
                              selfSay('You just swap '.. counts.count7[1] ..' '.. getItemName(items.item7[1]) ..' for '.. counts.count7[2] ..' '.. getItemName(items.item7[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count7[1] ..' '.. getItemName(items.item7[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'fireheart platemail') then
                    if getPlayerItemCount(cid, items.item8[1]) >= counts.count8[1] then
                              doPlayerRemoveItem(cid, items.item8[1], counts.count8[1])
                              doPlayerAddItem(cid, items.item8[2], counts.count8[2])
                              selfSay('You just swap '.. counts.count8[1] ..' '.. getItemName(items.item8[1]) ..' for '.. counts.count8[2] ..' '.. getItemName(items.item8[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count8[1] ..' '.. getItemName(items.item8[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'firemind raiment') then
                    if getPlayerItemCount(cid, items.item9[1]) >= counts.count9[1] then
                              doPlayerRemoveItem(cid, items.item9[1], counts.count9[1])
                              doPlayerAddItem(cid, items.item9[2], counts.count9[2])
                              selfSay('You just swap '.. counts.count9[1] ..' '.. getItemName(items.item9[1]) ..' for '.. counts.count9[2] ..' '.. getItemName(items.item9[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count9[1] ..' '.. getItemName(items.item9[1]) ..'.', cid)
                    end
                    
                    -- Dolls 
                    elseif msgcontains(msg, 'firesoul tabard') then
                    if getPlayerItemCount(cid, items.item10[1]) >= counts.count10[1] then
                              doPlayerRemoveItem(cid, items.item10[1], counts.count10[1])
                              doPlayerAddItem(cid, items.item10[2], counts.count10[2])
                              selfSay('You just swap '.. counts.count10[1] ..' '.. getItemName(items.item10[1]) ..' for '.. counts.count10[2] ..' '.. getItemName(items.item10[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count10[1] ..' '.. getItemName(items.item10[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'frostheart cuirass') then
                    if getPlayerItemCount(cid, items.item11[1]) >= counts.count11[1] then
                              doPlayerRemoveItem(cid, items.item11[1], counts.count11[1])
                              doPlayerAddItem(cid, items.item11[2], counts.count11[2])
                              selfSay('You just swap '.. counts.count11[1] ..' '.. getItemName(items.item11[1]) ..' for '.. counts.count11[2] ..' '.. getItemName(items.item11[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count11[1] ..' '.. getItemName(items.item11[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'frostheart hauberk') then
                    if getPlayerItemCount(cid, items.item12[1]) >= counts.count12[1] then
                              doPlayerRemoveItem(cid, items.item12[1], counts.count12[1])
                              doPlayerAddItem(cid, items.item12[2], counts.count12[2])
                              selfSay('You just swap '.. counts.count12[1] ..' '.. getItemName(items.item12[1]) ..' for '.. counts.count12[2] ..' '.. getItemName(items.item12[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count12[1] ..' '.. getItemName(items.item12[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'frostheart platemail') then
                    if getPlayerItemCount(cid, items.item13[1]) >= counts.count13[1] then
                              doPlayerRemoveItem(cid, items.item13[1], counts.count13[1])
                              doPlayerAddItem(cid, items.item13[2], counts.count13[2])
                              selfSay('You just swap '.. counts.count13[1] ..' '.. getItemName(items.item13[1]) ..' for '.. counts.count13[2] ..' '.. getItemName(items.item13[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count13[1] ..' '.. getItemName(items.item13[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'frostsoul tabard') then
                    if getPlayerItemCount(cid, items.item14[1]) >= counts.count14[1] then
                              doPlayerRemoveItem(cid, items.item14[1], counts.count14[1])
                              doPlayerAddItem(cid, items.item14[2], counts.count14[2])
                              selfSay('You just swap '.. counts.count14[1] ..' '.. getItemName(items.item14[1]) ..' for '.. counts.count14[2] ..' '.. getItemName(items.item14[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count14[1] ..' '.. getItemName(items.item14[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'earthheart hauberk') then
                    if getPlayerItemCount(cid, items.item1[1]) >= counts.count1[1] then
                              doPlayerRemoveItem(cid, items.item1[1], counts.count1[1])
                              doPlayerAddItem(cid, items.item1[2], counts.count1[2])
                              selfSay('You just swap '.. counts.count1[1] ..' '.. getItemName(items.item1[1]) ..' for '.. counts.count1[2] ..' '.. getItemName(items.item1[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count1[1] ..' '.. getItemName(items.item1[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'frostmind raiment') then
                    if getPlayerItemCount(cid, items.item15[1]) >= counts.count15[1] then
                              doPlayerRemoveItem(cid, items.item15[1], counts.count15[1])
                              doPlayerAddItem(cid, items.item15[2], counts.count15[2])
                              selfSay('You just swap '.. counts.count15[1] ..' '.. getItemName(items.item15[1]) ..' for '.. counts.count15[2] ..' '.. getItemName(items.item15[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count15[1] ..' '.. getItemName(items.item15[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'thunderheart cuirass') then
                    if getPlayerItemCount(cid, items.item16[1]) >= counts.count16[1] then
                              doPlayerRemoveItem(cid, items.item16[1], counts.count16[1])
                              doPlayerAddItem(cid, items.item16[2], counts.count16[2])
                              selfSay('You just swap '.. counts.count16[1] ..' '.. getItemName(items.item16[1]) ..' for '.. counts.count16[2] ..' '.. getItemName(items.item16[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count16[1] ..' '.. getItemName(items.item16[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'thunderheart hauberk') then
                    if getPlayerItemCount(cid, items.item17[1]) >= counts.count17[1] then
                              doPlayerRemoveItem(cid, items.item17[1], counts.count17[1])
                              doPlayerAddItem(cid, items.item17[2], counts.count17[2])
                              selfSay('You just swap '.. counts.count17[1] ..' '.. getItemName(items.item17[1]) ..' for '.. counts.count17[2] ..' '.. getItemName(items.item17[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count17[1] ..' '.. getItemName(items.item17[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'thunderheart platemail') then
                    if getPlayerItemCount(cid, items.item18[1]) >= counts.count18[1] then
                              doPlayerRemoveItem(cid, items.item18[1], counts.count18[1])
                              doPlayerAddItem(cid, items.item18[2], counts.count18[2])
                              selfSay('You just swap '.. counts.count18[1] ..' '.. getItemName(items.item18[1]) ..' for '.. counts.count18[2] ..' '.. getItemName(items.item18[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count18[1] ..' '.. getItemName(items.item18[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'thundermind raiment') then
                    if getPlayerItemCount(cid, items.item19[1]) >= counts.count19[1] then
                              doPlayerRemoveItem(cid, items.item19[1], counts.count19[1])
                              doPlayerAddItem(cid, items.item19[2], counts.count19[2])
                              selfSay('You just swap '.. counts.count19[1] ..' '.. getItemName(items.item19[1]) ..' for '.. counts.count19[2] ..' '.. getItemName(items.item19[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count19[1] ..' '.. getItemName(items.item19[1]) ..'.', cid)
                    end
                    
                    elseif msgcontains(msg, 'thundersoul tabard') then
                    if getPlayerItemCount(cid, items.item20[1]) >= counts.count20[1] then
                              doPlayerRemoveItem(cid, items.item20[1], counts.count20[1])
                              doPlayerAddItem(cid, items.item20[2], counts.count20[2])
                              selfSay('You just swap '.. counts.count20[1] ..' '.. getItemName(items.item20[1]) ..' for '.. counts.count20[2] ..' '.. getItemName(items.item20[2]) ..'.', cid)
                    else
                              selfSay('You need '.. counts.count20[1] ..' '.. getItemName(items.item20[1]) ..'.', cid)
                    end                    
                    
          end
          
          return TRUE
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

 

Link para o post
Compartilhar em outros sites
16 minutos atrás, Renildo disse:

qual web site compatível? não encontro um que de certo.

 

Gostaria de saber também quem tiver posta ai desde já agradeço.

 Gesior 2012, os ajustes terão que ser feitos manualmente...

Link para o post
Compartilhar em outros sites

@Renildo Experimente esse, foi editado por mim e é preciso fazer a configuração de acordo com o seu servidor.

site:

Nosso amigo   @Rockersz  está editando tbm um gesior.

ATT,

Jaurez

Editado por Jaurez (veja o histórico de edições)
Link para o post
Compartilhar em outros sites

Mapa 98% revisado, incluindo a remoção da flor em rookgard:

Scan:

https://www.virustotal.com/pt/file/24b1dd38b89af87d8693c1a56ad1d7445d13406100c3abc1d7130d3b4ccdc4ea/analysis/1490456640/

 

@malucooo, estou com tempo para testar quaisquer alterações que vc faça.

 

 

global.zip

23 horas atrás, Jaurez disse:

@Renildo Experimente esse, foi editado por mim e é preciso fazer a configuração de acordo com o seu servidor.

site:

Nosso amigo   @Rockersz  está editando tbm um gesior.

ATT,

Jaurez

Estou trabalhando em um sitezinho legal, tô quase lá, assim que estiver pronto eu disponibilizo aqui pra vocês, abraço!

 

Site online: http://200.101.79.96:500

Editado por Rockersz (veja o histórico de edições)

CONHEÇA MEU PROJETO:

WWW.ETERNUS-GLOBAL.COM

 

tibia-logo.gif

Link para o post
Compartilhar em outros sites

Adicionado as Tibia coins no market e um remake no walkfield system...

 

use as flags abaixo para configurar seus monstros

 

<flag canwalkonenergy="0" />

 <flag canwalkonfire="0" />

 <flag canwalkonpoison="0" />

 

ao substituir o "0" por "1" o monstro passa no field qndo atacado!

 

listem os bugs e parem de me falar em website e customizações de client!

Estamos com problemas no gihutb, então entrem nos dois repositorios e verifiquem o mais recente!

http://www.github.com/malucooo/otxserver-global/ ou http://www.github.com/malucooo/otxserver-new/

Editado por malucooo (veja o histórico de edições)

 

 

O melhor conteúdo da atualidade!

http://www.gitlab.com/malucooo/otxserver-new/

- Full Global Map with 12.xx updates, all quests and many features!

- Protocol 12.31

Link para o post
Compartilhar em outros sites
5 horas atrás, malucooo disse:

Adicionado as Tibia coins no market e um remake no walkfield system...

 

use as flags abaixo para configurar seus monstros

 

<flag canwalkonenergy="0" />

 <flag canwalkonfire="0" />

 <flag canwalkonpoison="0" />

 

ao substituir o "0" por "1" o monstro passa no field qndo atacado!

 

listem os bugs e parem de me falar em website e customizações de client!

Estamos com problemas no gihutb, então entrem nos dois repositorios e verifiquem o mais recente!

http://www.github.com/malucooo/otxserver-global/ ou http://www.github.com/malucooo/otxserver-new/

 

baixando e testando em seguida.

 

EDIT:

Os tibia coins no market estão 100% funcionando, mas para reconhecer certinho, tem que alterar o arquivo init.lua em: data/modules/scripts/gamestore e colocar esse script:

-- Please don't edit those information!
GameStore = {
    ModuleName = "GameStore",
    Developer = "OTX TEAM",
    Version = "0.3",
    LastUpdated = "24-09-2016 07:15PM"
}
--== Enums ==--
GameStore.OfferTypes = {
    OFFER_TYPE_NONE = 0, -- (this will disable offer)
    OFFER_TYPE_ITEM = 1,
    OFFER_TYPE_STACKABLE = 2,
    OFFER_TYPE_OUTFIT = 3,
    OFFER_TYPE_OUTFIT_ADDON = 4,
    OFFER_TYPE_MOUNT = 5,
    OFFER_TYPE_NAMECHANGE = 6,
    OFFER_TYPE_SEXCHANGE = 7,
    OFFER_TYPE_PROMOTION = 8
}
GameStore.ClientOfferTypes = {
    CLIENT_STORE_OFFER_OTHER = 0,
    CLIENT_STORE_OFFER_NAMECHANGE = 1
}
GameStore.HistoryTypes = {
    HISTORY_TYPE_NONE = 0,
    HISTORY_TYPE_GIFT = 1,
    HISTORY_TYPE_REFUND = 2
}
GameStore.States = {
    STATE_NONE = 0,
    STATE_NEW = 1,
    STATE_SALE = 2,
    STATE_TIMED = 3
}
GameStore.StoreErrors = {
    STORE_ERROR_PURCHASE = 0,
    STORE_ERROR_NETWORK = 1,
    STORE_ERROR_HISTORY = 2,
    STORE_ERROR_TRANSFER = 3,
    STORE_ERROR_INFORMATION = 4
}
GameStore.ServiceTypes = {
    SERVICE_STANDERD = 0,
    SERVICE_OUTFITS = 3,
    SERVICE_MOUNTS = 4
}
GameStore.SendingPackets = {
    S_CoinBalance = 0xDF, -- 223
    S_StoreError = 0xE0, -- 224
    S_RequestPurchaseData = 0xE1, -- 225
    S_CoinBalanceUpdating = 0xF2, -- 242
    S_OpenStore = 0xFB, -- 251
    S_StoreOffers = 0xFC, -- 252
    S_OpenTransactionHistory = 0xFD, -- 253
    S_CompletePurchase = 0xFE  -- 254
}
GameStore.RecivedPackets = {
    C_StoreEvent = 0xE9, -- 233
    C_TransferCoins = 0xEF, -- 239
    C_OpenStore = 0xFA, -- 250
    C_RequestStoreOffers = 0xFB, -- 251
    C_BuyStoreOffer = 0xFC, -- 252
    C_OpenTransactionHistory = 0xFD, -- 253
    C_RequestTransactionHistory = 0xFE, -- 254
}
GameStore.DefaultValues = {
    DEFAULT_VALUE_ENTRIES_PER_PAGE    = 16
}
GameStore.DefaultDescriptions = {
    OUTFIT = {"This outfit looks nice. Only high-class people are able to wear it!",
        "An outfit that was created to suit you. We are sure you'll like it.",
        "Legend says only smart people should wear it, otherwise you will burn!"},
    MOUNT = {"This is a fantastic mount that helps to become faster, try it!",
        "The first rider of this mount became the leader of his country! legends say that."},
    NAMECHANGE = {"Are you hunted? Tired of that? Get a new name, a new life!",
        "A new name to suit your needs!"},
    SEXCHANGE = {"Bored of your character's sex? Get a new sex for him now!!"}
}
--==Parsing==--
GameStore.isItsPacket = function(byte)
    for k, v in pairs(GameStore.RecivedPackets) do
        if v == byte then
            return true
        end
    end
    return false
end
function onRecvbyte(player, msg, byte)
    if byte == GameStore.RecivedPackets.C_StoreEvent then
        -- Not Used!
    elseif byte == GameStore.RecivedPackets.C_TransferCoins then
        parseTransferCoins(player, msg)
    elseif byte == GameStore.RecivedPackets.C_OpenStore then
        parseOpenStore(player, msg)
    elseif byte == GameStore.RecivedPackets.C_RequestStoreOffers then
        parseRequestStoreOffers(player, msg)
    elseif byte == GameStore.RecivedPackets.C_BuyStoreOffer then
        parseBuyStoreOffer(player, msg)
    elseif byte == GameStore.RecivedPackets.C_OpenTransactionHistory then
        parseOpenTransactionHistory(player, msg)
    elseif byte == GameStore.RecivedPackets.C_RequestTransactionHistory then
        parseRequestTransactionHistory(player, msg)
    end
    return true
end
function parseTransferCoins(player, msg)
    local reciver = msg:getString()
    local amount = msg:getU32()
    if reciver:lower() == player:getName():lower() then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You can't transfer coins to yourself.")
    end
    local resultId = db.storeQuery("SELECT `account_id` FROM `players` WHERE `name` = " .. db.escapeString(reciver:lower()) .. "")
    if not resultId then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "We couldn't find that player.")
    end
    local accountId = result.getDataInt(resultId, "account_id")
    if accountId == player:getAccountId() then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You cannot transfer coin to a character in the same account.")
    end
    if not player:canRemoveCoins(amount) then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You don't have enough funds to transfer these coins.")
    end
    player:removeCoinsBalance(amount)
    db.asyncQuery("UPDATE `accounts` SET `coins` = `coins` + " .. amount .. " WHERE `id` = " .. accountId)
    addPlayerEvent(sendStorePurchaseSuccessful, 550, player, "You have transfered " .. amount .. " coins to " .. reciver .. " successfully")
    -- Adding history for both reciver/sender
    GameStore.insertHistory(accountId, GameStore.HistoryTypes.HISTORY_TYPE_NONE, player:getName() .. " transfered you this amount.", amount)
    GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, "You transfered this amount to " .. reciver, -1 * amount) -- negative
end
function parseOpenStore(player, msg)
    openStore(player)
    local serviceType = msg:getByte()
    local category = GameStore.Categories and GameStore.Categories[1] or nil
    if serviceType == GameStore.ServiceTypes.SERVICE_OUTFITS then
        category = GameStore.getCategoryByName("outfits")
    elseif serviceType == GameStore.ServiceTypes.SERVICE_MOUNTS then
        category = GameStore.getCategoryByName("mounts")
    end
    if category then
        addPlayerEvent(sendShowStoreOffers, 350, player, category)
    end
end
function parseRequestStoreOffers(player, msg)
    local serviceType = GameStore.ServiceTypes.SERVICE_STANDERD
    if player:getClient().version >= 1092 then
        serviceType = msg:getByte()
    end
    local categoryName = msg:getString()
    local category = GameStore.getCategoryByName(categoryName)
    if category then
        addPlayerEvent(sendShowStoreOffers, 350, player, category)
    end
end
function parseBuyStoreOffer(player, msg)
    local offerId = msg:getU32()
    local productType = msg:getByte()
    local offer = GameStore.getOfferById(offerId)
    if offer then
        -- If we don't add type, or offer type is fake
        if not offer.type or offer.type == GameStore.OfferTypes.OFFER_TYPE_NONE then
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "The offer is either fake or corrupt.")
        end
        -- If no thing id,
        if offer.type ~= GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE and not offer.thingId then
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "The offer is either fake or corrupt.")
        end
        -- We remove coins before doing everything, if it fails, we add coins back!
        if not player:canRemoveCoins(offer.price) then
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "We couldn't remove coins from your account, try again later.")
        end
        -- count is used in type(item), so we need to show (i.e 10x crystal coins)
        local offerCountStr = offer.count and (offer.count .. "x ") or ""
        -- The message which we will send to player!
        local message = "You have purchased " .. offerCountStr .. offer.name .. " for " .. offer.price .. " coins."
        -- If offer is item.
        if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM then
            local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
            if inbox and inbox:getEmptySlots() > offer.count then
                if player:getFreeCapacity() > ItemType(offer.thingId):getWeight(offer.count or 1) then
                    for t = 1,offer.count do
                        inbox:addItem(offer.thingId, offer.count or 1)
                    end
                else
                    return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You don't have enough capacity.")
                end
            else
                return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "Please make sure you have free slots in your store inbox.")
            end
            -- If offer is Stackable.
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_STACKABLE then
            local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
            if inbox and inbox:getEmptySlots() > 0 then
                if player:getFreeCapacity() > (ItemType(offer.thingId):getWeight(offer.count or 1) + ItemType(2596):getWeight(1)) then -- if player has cap for a parcel + offer weight
                    local parcel = inbox:addItem(2596, 1)
                    local packagename = ''.. offer.count..'x '.. offer.name ..' package.'
                    local pendingCount = offer.count;
                    if parcel then
                        parcel:setAttribute(ITEM_ATTRIBUTE_NAME, packagename)
                        while pendingCount > 0  do
                            if(pendingCount <= 100) then
                                parcel:addItem(offer.thingId, pendingCount)
                                pendingCount = 0
                            else
                                parcel:addItem(offer.thingId, 100)
                                pendingCount= pendingCount - 100
                            end
                        end
                    else --error creating the parcel item
                        return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "There was an error processing your purchase and your coins were not used. If this error persists, contact someone from staff.")
                    end
                else
                    return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You don't have enough capacity.")
                end
            else
                return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "Please make sure you have free slots in your store inbox.")
            end
            -- If offer is outfit/addon
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT or offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
            local outfitLookType
            if player:getSex() == PLAYERSEX_MALE then
                outfitLookType = offer.thingId.male
            else
                outfitLookType = offer.thingId.female
            end
            if not outfitLookType then
                return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "This outfit seems not to suit your sex, we are sorry for that!")
            end
            player:addOutfitAddon(outfitLookType, offer.addon or 0)
            -- If offer is mount
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_MOUNT then
            player:addMount(offer.thingId)
            -- If offer is name change
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE then
            -- If player typed name yet!
            if productType == GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE then
                local newName = msg:getString()
                local resultId = db.storeQuery("SELECT * FROM `players` WHERE `name` = " .. db.escapeString(newName) .. "")
                if resultId ~= false then
                    return addPlayerEvent(sendStoreError, 650, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "This name is already used, please try again!")
                end
                local result = GameStore.canChangeToName(newName)
                if not result.ability then
                    return addPlayerEvent(sendStoreError, 650, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, result.reason)
                end
                newName = newName:lower():gsub("(%l)(%w*)", function(a, b) return string.upper(a) .. b end)
                db.asyncQuery("UPDATE `players` SET `name` = " .. db.escapeString(newName) .. " WHERE `id` = " .. player:getGuid())
                message =  "You have successfully changed you name, you must relog to see changes."
                -- If not, we ask him to do!
            else
                return addPlayerEvent(sendRequestPurchaseData, 250, player, offer.id, GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE)
            end
            -- If offer is sex change
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE then
            player:toggleSex()
            -- If offer is promotion
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PROMOTION then
            if not GameStore.addPromotionToPlayer(player, offer.thingId) then
                return false
            end
            -- You can add whatever offer types to suit your needs!
        else
            -- ToDo :: implement purchase function
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "This offer is fake, please contact admin.")
        end
        -- Removing coins
        player:removeCoinsBalance(offer.price)
        -- We add this purchase to history!
        GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, offerCountStr .. offer.name, offer.price * -1)
        -- Send to client that purchase is successful!
        return addPlayerEvent(sendStorePurchaseSuccessful, 650, player, message)
    end
    -- If we didn't found the offer or error happened
    addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_INFORMATION, "We couldn't locate this offer, please try again later.")
end
-- Both functions use same formula!
function parseOpenTransactionHistory(player, msg)
    local page = 1
    GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE = msg:getByte()
    sendStoreTransactionHistory(player, page, GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE)
end
function parseRequestTransactionHistory(player, msg)
    local page = msg:getU32()
    sendStoreTransactionHistory(player, page, GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE)
end
--==Sending==--
function openStore(player)
    if not GameStore.Categories then
        return false
    end
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_OpenStore)
    msg:addByte(0x00)
    msg:addU16(#GameStore.Categories)
    for k, category in ipairs(GameStore.Categories) do
        msg:addString(category.name)
        msg:addString(category.description)
        if player:getClient().version >= 1093 then
            msg:addByte(category.state or GameStore.States.STATE_NONE)
        end
        msg:addByte(#category.icons)
        for m, icon in ipairs(category.icons) do
            msg:addString(icon)
        end
        msg:addString(category.parentCategory)
    end
    msg:sendToPlayer(player)
    sendCoinBalanceUpdating(player, true)
end
function sendShowStoreOffers(player, category)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_StoreOffers)
    msg:addString(category.name)
    msg:addU16(category.offers and #category.offers or 0x00)
    if category.offers then
        for k, offer in ipairs(category.offers) do
            msg:addU32(offer.id and offer.id or 0xFFFF) -- we later detect this number!
            local name = ""
            if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM and offer.count then
                name = offer.count .. "x "
            end
            if offer.type == GameStore.OfferTypes.OFFER_TYPE_STACKABLE and offer.count then
                name = offer.count .. "x "
            end
            name = name .. (offer.name or "Something Special")
            msg:addString(name)
            msg:addString(offer.description or GameStore.getDefaultDescription(offer.type))
            msg:addU32(offer.price and offer.price or 0xFFFF)
            msg:addByte(offer.state or GameStore.States.STATE_NONE) -- default is none
            local disabled, disabledReason = 0, ""
            if offer.disabled == true or not offer.type then
                disabled = 1
            end
            if offer.type ~= GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE and not offer.thingId then
                disabled = 1
            end
            if disabled == 1 and offer.disabledReason then -- dynamic disable
                disabledReason = offer.disabledReason
            end
            if disabled ~= 1 then
                if offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT or offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
                    local outfitLookType
                    if player:getSex() == PLAYERSEX_MALE then
                        outfitLookType = offer.thingId.male
                    else
                        outfitLookType = offer.thingId.female
                    end
                    if outfitLookType then
                        if offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT and player:hasOutfit(outfitLookType) then
                            disabled = 1
                            disabledReason = "You already have this outfit."
                        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
                            if player:hasOutfit(outfitLookType) then
                                if player:hasOutfit(outfitLookType, offer.addon) then
                                    disabled = 1
                                    disabledReason = "You already have this addon."
                                end
                            else
                                disabled = 1
                                disabledReason = "You don't have the outfit, you can't buy the addon."
                            end
                        end
                    else
                        disabled = 1
                        disabledReason = "The offer is fake."
                    end
                elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_MOUNT then
                    local hasMount = player:hasMount(offer.thingId)
                    if hasMount == true then
                        disabled = 1
                        disabledReason = "You already have this mount."
                    end
                elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PROMOTION then
                    if GameStore.canAddPromotionToPlayer(player, offer.thingId).ability == false then
                        disabled = 1
                        disabledReason = "You can't get this promotion"
                    end
                end
            end
            msg:addByte(disabled)
            if disabled == 1 and player:getClient().version >= 1093 then
                msg:addString(disabledReason)
            end
            msg:addByte(#offer.icons)
            for k, icon in ipairs(offer.icons) do
                msg:addString(icon)
            end
            msg:addU16(0) -- We still don't support SubOffers!
        end
    end
    msg:sendToPlayer(player)
end
function sendStoreTransactionHistory(player, page, entriesPerPage)
    local entries = GameStore.retrieveHistoryEntries(player:getAccountId()) -- this makes everything easy!
    if #entries == 0 then
        return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_HISTORY, "You don't have any entries yet.")
    end
    local toSkip = (page - 1) * entriesPerPage
    for i = 1, toSkip do
        table.remove(entries, 1) -- we remove first!
    end
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_OpenTransactionHistory)
    msg:addU32(page)
    msg:addU32(#entries > entriesPerPage and 0x01 or 0x00)
    msg:addByte(#entries >= entriesPerPage and entriesPerPage or #entries)
    for k, entry in ipairs(entries) do
        if k >= entriesPerPage then break end
        msg:addU32(entry.time)
        msg:addByte(entry.mode)
        msg:addU32(entry.amount)
        msg:addString(entry.description)
    end
    msg:sendToPlayer(player)
end
function sendStorePurchaseSuccessful(player, message)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_CompletePurchase)
    msg:addByte(0x00)
    msg:addString(message)
    msg:addU32(player:getCoinsBalance())
    msg:addU32(player:getCoinsBalance())
    msg:sendToPlayer(player)
end
function sendStoreError(player, errorType, message)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_StoreError)
    msg:addByte(errorType)
    msg:addString(message)
    msg:sendToPlayer(player)
end
function sendCoinBalanceUpdating(player, updating)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_CoinBalanceUpdating)
    msg:addByte(0x00)
    msg:sendToPlayer(player)
    if updating == true then
        sendUpdateCoinBalance(player)
    end
end
function sendUpdateCoinBalance(player)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_CoinBalanceUpdating)
    msg:addByte(0x01)
    msg:addByte(GameStore.SendingPackets.S_CoinBalance)
    msg:addByte(0x01)
    msg:addU32(player:getCoinsBalance())
    msg:addU32(player:getCoinsBalance())
    msg:sendToPlayer(player)
end
function sendRequestPurchaseData(player, offerId, type)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_RequestPurchaseData)
    msg:addU32(offerId)
    msg:addByte(type)
    msg:sendToPlayer(player)
end
--==GameStoreFunctions==--
GameStore.getCategoryByName = function(name)
    for k, category in ipairs(GameStore.Categories) do
        if category.name:lower() == name:lower() then
            return category
        end
    end
    return nil
end
GameStore.getOfferById = function(id)
    for Cat_k, category in ipairs(GameStore.Categories) do
        if category.offers then
            for Off_k, offer in ipairs(category.offers) do
                if offer.id == id then
                    return offer
                end
            end
        end
    end
    return nil
end
GameStore.insertHistory = function(accountId, mode, description, amount)
    return db.asyncQuery(string.format("INSERT INTO `store_history`(`account_id`, `mode`, `description`, `coin_amount`, `time`) VALUES (%s, %s, %s, %s, %s)", accountId, mode, db.escapeString(description), amount, os.time()))
end
GameStore.retrieveHistoryEntries = function(accountId)
    local entries = {}
    local resultId = db.storeQuery("SELECT * FROM `store_history` WHERE `account_id` = " .. accountId .. " ORDER BY `time` DESC LIMIT 15;")
    if resultId ~= false then
        repeat
            local entry = {
                mode = result.getDataInt(resultId, "mode"),
                description = result.getDataString(resultId, "description"),
                amount = result.getDataInt(resultId, "coin_amount"),
                time = result.getDataInt(resultId, "time"),
            }
            table.insert(entries, entry)
        until not result.next(resultId)
        result.free(resultId)
    end
    return entries
end
GameStore.getDefaultDescription = function(offerType)
    local t, descList = GameStore.OfferTypes
    if offerType == t.OFFER_TYPE_OUTFIT or offerType == t.OFFER_TYPE_OUTFIT_ADDON then
        descList = GameStore.DefaultDescriptions.OUTFIT
    elseif offerType == t.OFFER_TYPE_MOUNT then
        descList = GameStore.DefaultDescriptions.MOUNT
    elseif offerType == t.OFFER_TYPE_NAMECHANGE then
        descList = GameStore.DefaultDescriptions.NAMECHANGE
    elseif offerType == t.OFFER_TYPE_SEXCHANGE then
        descList = GameStore.DefaultDescriptions.SEXCHANGE
    else
        return ""
    end
    return descList[math.floor(math.random(1, #descList))] or ""
end
GameStore.canChangeToName = function(name)
    local result = {
        ability = false
    }
    if name:len() < 3 or name:len() > 14 then
        result.reason = "Your new name's length should be lower than 3 or higher than 14."
        return result
    end
    -- just copied from znote aac.
    local words = {"owner", "gamemaster", "hoster", "admin", "staff", "tibia", "account", "god", "anal", "ass", "fuck", "sex", "hitler", "pussy", "dick", "rape", "cm", "gm", "tutor", "counsellor"}
    local split = name:split(" ")
    for k, word in ipairs(words) do
        for k, nameWord in ipairs(split) do
            if nameWord:lower() == word then
                result.reason = "You can't use word \"" .. word .. "\" in your new name."
                return result
            end
        end
    end
    if MonsterType(name) then
        result.reason = "Your new name \"" .. name .. "\" can't be a monster's name."
        return result
    elseif Npc(name) then
        result.reason = "Your new name \"" .. name .. "\" can't be a npc's name."
        return result
    end
    local letters = "{}|_*+-=<>0123456789@#%^&()/*\\.,:;~!\"$"
    for i = 1, letters:len() do
        local c = letters:sub(i, i)
        for i = 1, name:len() do
            local m = name:sub(i, i)
            if m == c then
                result.reason = "You can't use this letter \"" .. c .. "\" in your new name."
                return result
            end
        end
    end
    result.ability = true
    return result
end
GameStore.canAddPromotionToPlayer = function(player, promotion, send)
    local result = {
        ability = true
    }
    local vocation = player:getVocation()
    -- Working --
    local vocationCopy, baseVocation = vocation, vocation
    vocation = vocation:getDemotion()
    while vocation do
        baseVocation = vocation
        vocation = vocation:getDemotion()
    end
    local baseVocationsCount = GameStore.BaseVocationsCount or 4
    local newVocId = (baseVocationsCount * promotion) + baseVocation:getId()
    if not Vocation(newVocId) then
        if send then
            addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "The offer is fake, please report it!")
        end
        result.ability = false
        return result
    end
    -- If promotion is less than player's voc, or player don't have previous promotion
    if newVocId <= vocationCopy:getId() then
        if send then
            addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You already have this promotion!")
        end
        result.ability = false
        return result
    end
    if (newVocId - baseVocationsCount) ~= vocationCopy:getId() then
        if send then
            addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You need higher promotion to get his one.")
        end
        result.ability = false
        return result
    end
    result.vocId = newVocId
    return result
end
GameStore.addPromotionToPlayer = function(player, promotion)
    local result = GameStore.canAddPromotionToPlayer(player, promotion, true)
    if result.ability == false then return false end
    local basics = {
        health = 185,
        mana = 40,
        cap = 500
    }
    player:setVocation(result.vocId)
    local newVoc = player:getVocation()
    player:setMaxHealth(basics.health + (newVoc:getHealthGain() * player:getLevel()))
    player:setMaxMana(basics.mana + (newVoc:getManaGain() * player:getLevel()))
    player:setCapacity(basics.cap + (newVoc:getCapacityGain() * player:getLevel()))
    player:addHealth(player:getMaxHealth())
    player:addMana(player:getMaxMana())
    player:sendTextMessage(MESSAGE_INFO_DESCR, "You have been promoted to " .. newVoc:getName())
    return true
end
--==Player==--
function Player.getCoinsBalance(self)
    resultId = db.storeQuery("SELECT `coins` FROM `accounts` WHERE `id` = " .. self:getAccountId())
    if not resultId then return 0 end
    return result.getDataInt(resultId, "coins")
end
function Player.setCoinsBalance(self, coins)
    db.asyncQuery("UPDATE `accounts` SET `coins` = " .. coins .. " WHERE `id` = " .. self:getAccountId())
    return true
end
function Player.canRemoveCoins(self, coins)
    if self:getCoinsBalance() < coins then
        return false
    end
    return true
end
function Player.removeCoinsBalance(self, coins)
    if self:canRemoveCoins(coins) then
        return self:setCoinsBalance(self:getCoinsBalance() - coins)
    end
    return false
end
function Player.addCoinsBalance(self, coins, update)
    self:setCoinsBalance(self:getCoinsBalance() + coins)
    if update then sendCoinBalanceUpdating(self, true) end
    return true
end
function Player.toggleSex(self)
    local currentSex = self:getSex()
    local playerOutfit = self:getOutfit()
    if currentSex == PLAYERSEX_FEMALE then
        self:setSex(PLAYERSEX_MALE)
        playerOutfit.lookType = 128
    else
        self:setSex(PLAYERSEX_FEMALE)
        playerOutfit.lookType = 136
    end
    self:setOutfit(playerOutfit)
end

Pois estava pegando premium_points ao invés de coins. Parabéns @malucooo, excelente trabalho.

 

Editado por Rockersz (veja o histórico de edições)

CONHEÇA MEU PROJETO:

WWW.ETERNUS-GLOBAL.COM

 

tibia-logo.gif

Link para o post
Compartilhar em outros sites
6 horas atrás, Rockersz disse:

 

baixando e testando em seguida.

 

EDIT:

Os tibia coins no market estão 100% funcionando, mas para reconhecer certinho, tem que alterar o arquivo init.lua em: data/modules/scripts/gamestore e colocar esse script:


-- Please don't edit those information!
GameStore = {
    ModuleName = "GameStore",
    Developer = "OTX TEAM",
    Version = "0.3",
    LastUpdated = "24-09-2016 07:15PM"
}
--== Enums ==--
GameStore.OfferTypes = {
    OFFER_TYPE_NONE = 0, -- (this will disable offer)
    OFFER_TYPE_ITEM = 1,
    OFFER_TYPE_STACKABLE = 2,
    OFFER_TYPE_OUTFIT = 3,
    OFFER_TYPE_OUTFIT_ADDON = 4,
    OFFER_TYPE_MOUNT = 5,
    OFFER_TYPE_NAMECHANGE = 6,
    OFFER_TYPE_SEXCHANGE = 7,
    OFFER_TYPE_PROMOTION = 8
}
GameStore.ClientOfferTypes = {
    CLIENT_STORE_OFFER_OTHER = 0,
    CLIENT_STORE_OFFER_NAMECHANGE = 1
}
GameStore.HistoryTypes = {
    HISTORY_TYPE_NONE = 0,
    HISTORY_TYPE_GIFT = 1,
    HISTORY_TYPE_REFUND = 2
}
GameStore.States = {
    STATE_NONE = 0,
    STATE_NEW = 1,
    STATE_SALE = 2,
    STATE_TIMED = 3
}
GameStore.StoreErrors = {
    STORE_ERROR_PURCHASE = 0,
    STORE_ERROR_NETWORK = 1,
    STORE_ERROR_HISTORY = 2,
    STORE_ERROR_TRANSFER = 3,
    STORE_ERROR_INFORMATION = 4
}
GameStore.ServiceTypes = {
    SERVICE_STANDERD = 0,
    SERVICE_OUTFITS = 3,
    SERVICE_MOUNTS = 4
}
GameStore.SendingPackets = {
    S_CoinBalance = 0xDF, -- 223
    S_StoreError = 0xE0, -- 224
    S_RequestPurchaseData = 0xE1, -- 225
    S_CoinBalanceUpdating = 0xF2, -- 242
    S_OpenStore = 0xFB, -- 251
    S_StoreOffers = 0xFC, -- 252
    S_OpenTransactionHistory = 0xFD, -- 253
    S_CompletePurchase = 0xFE  -- 254
}
GameStore.RecivedPackets = {
    C_StoreEvent = 0xE9, -- 233
    C_TransferCoins = 0xEF, -- 239
    C_OpenStore = 0xFA, -- 250
    C_RequestStoreOffers = 0xFB, -- 251
    C_BuyStoreOffer = 0xFC, -- 252
    C_OpenTransactionHistory = 0xFD, -- 253
    C_RequestTransactionHistory = 0xFE, -- 254
}
GameStore.DefaultValues = {
    DEFAULT_VALUE_ENTRIES_PER_PAGE    = 16
}
GameStore.DefaultDescriptions = {
    OUTFIT = {"This outfit looks nice. Only high-class people are able to wear it!",
        "An outfit that was created to suit you. We are sure you'll like it.",
        "Legend says only smart people should wear it, otherwise you will burn!"},
    MOUNT = {"This is a fantastic mount that helps to become faster, try it!",
        "The first rider of this mount became the leader of his country! legends say that."},
    NAMECHANGE = {"Are you hunted? Tired of that? Get a new name, a new life!",
        "A new name to suit your needs!"},
    SEXCHANGE = {"Bored of your character's sex? Get a new sex for him now!!"}
}
--==Parsing==--
GameStore.isItsPacket = function(byte)
    for k, v in pairs(GameStore.RecivedPackets) do
        if v == byte then
            return true
        end
    end
    return false
end
function onRecvbyte(player, msg, byte)
    if byte == GameStore.RecivedPackets.C_StoreEvent then
        -- Not Used!
    elseif byte == GameStore.RecivedPackets.C_TransferCoins then
        parseTransferCoins(player, msg)
    elseif byte == GameStore.RecivedPackets.C_OpenStore then
        parseOpenStore(player, msg)
    elseif byte == GameStore.RecivedPackets.C_RequestStoreOffers then
        parseRequestStoreOffers(player, msg)
    elseif byte == GameStore.RecivedPackets.C_BuyStoreOffer then
        parseBuyStoreOffer(player, msg)
    elseif byte == GameStore.RecivedPackets.C_OpenTransactionHistory then
        parseOpenTransactionHistory(player, msg)
    elseif byte == GameStore.RecivedPackets.C_RequestTransactionHistory then
        parseRequestTransactionHistory(player, msg)
    end
    return true
end
function parseTransferCoins(player, msg)
    local reciver = msg:getString()
    local amount = msg:getU32()
    if reciver:lower() == player:getName():lower() then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You can't transfer coins to yourself.")
    end
    local resultId = db.storeQuery("SELECT `account_id` FROM `players` WHERE `name` = " .. db.escapeString(reciver:lower()) .. "")
    if not resultId then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "We couldn't find that player.")
    end
    local accountId = result.getDataInt(resultId, "account_id")
    if accountId == player:getAccountId() then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You cannot transfer coin to a character in the same account.")
    end
    if not player:canRemoveCoins(amount) then
        return addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_TRANSFER, "You don't have enough funds to transfer these coins.")
    end
    player:removeCoinsBalance(amount)
    db.asyncQuery("UPDATE `accounts` SET `coins` = `coins` + " .. amount .. " WHERE `id` = " .. accountId)
    addPlayerEvent(sendStorePurchaseSuccessful, 550, player, "You have transfered " .. amount .. " coins to " .. reciver .. " successfully")
    -- Adding history for both reciver/sender
    GameStore.insertHistory(accountId, GameStore.HistoryTypes.HISTORY_TYPE_NONE, player:getName() .. " transfered you this amount.", amount)
    GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, "You transfered this amount to " .. reciver, -1 * amount) -- negative
end
function parseOpenStore(player, msg)
    openStore(player)
    local serviceType = msg:getByte()
    local category = GameStore.Categories and GameStore.Categories[1] or nil
    if serviceType == GameStore.ServiceTypes.SERVICE_OUTFITS then
        category = GameStore.getCategoryByName("outfits")
    elseif serviceType == GameStore.ServiceTypes.SERVICE_MOUNTS then
        category = GameStore.getCategoryByName("mounts")
    end
    if category then
        addPlayerEvent(sendShowStoreOffers, 350, player, category)
    end
end
function parseRequestStoreOffers(player, msg)
    local serviceType = GameStore.ServiceTypes.SERVICE_STANDERD
    if player:getClient().version >= 1092 then
        serviceType = msg:getByte()
    end
    local categoryName = msg:getString()
    local category = GameStore.getCategoryByName(categoryName)
    if category then
        addPlayerEvent(sendShowStoreOffers, 350, player, category)
    end
end
function parseBuyStoreOffer(player, msg)
    local offerId = msg:getU32()
    local productType = msg:getByte()
    local offer = GameStore.getOfferById(offerId)
    if offer then
        -- If we don't add type, or offer type is fake
        if not offer.type or offer.type == GameStore.OfferTypes.OFFER_TYPE_NONE then
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "The offer is either fake or corrupt.")
        end
        -- If no thing id,
        if offer.type ~= GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE and not offer.thingId then
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "The offer is either fake or corrupt.")
        end
        -- We remove coins before doing everything, if it fails, we add coins back!
        if not player:canRemoveCoins(offer.price) then
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "We couldn't remove coins from your account, try again later.")
        end
        -- count is used in type(item), so we need to show (i.e 10x crystal coins)
        local offerCountStr = offer.count and (offer.count .. "x ") or ""
        -- The message which we will send to player!
        local message = "You have purchased " .. offerCountStr .. offer.name .. " for " .. offer.price .. " coins."
        -- If offer is item.
        if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM then
            local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
            if inbox and inbox:getEmptySlots() > offer.count then
                if player:getFreeCapacity() > ItemType(offer.thingId):getWeight(offer.count or 1) then
                    for t = 1,offer.count do
                        inbox:addItem(offer.thingId, offer.count or 1)
                    end
                else
                    return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You don't have enough capacity.")
                end
            else
                return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "Please make sure you have free slots in your store inbox.")
            end
            -- If offer is Stackable.
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_STACKABLE then
            local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
            if inbox and inbox:getEmptySlots() > 0 then
                if player:getFreeCapacity() > (ItemType(offer.thingId):getWeight(offer.count or 1) + ItemType(2596):getWeight(1)) then -- if player has cap for a parcel + offer weight
                    local parcel = inbox:addItem(2596, 1)
                    local packagename = ''.. offer.count..'x '.. offer.name ..' package.'
                    local pendingCount = offer.count;
                    if parcel then
                        parcel:setAttribute(ITEM_ATTRIBUTE_NAME, packagename)
                        while pendingCount > 0  do
                            if(pendingCount <= 100) then
                                parcel:addItem(offer.thingId, pendingCount)
                                pendingCount = 0
                            else
                                parcel:addItem(offer.thingId, 100)
                                pendingCount= pendingCount - 100
                            end
                        end
                    else --error creating the parcel item
                        return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "There was an error processing your purchase and your coins were not used. If this error persists, contact someone from staff.")
                    end
                else
                    return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You don't have enough capacity.")
                end
            else
                return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "Please make sure you have free slots in your store inbox.")
            end
            -- If offer is outfit/addon
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT or offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
            local outfitLookType
            if player:getSex() == PLAYERSEX_MALE then
                outfitLookType = offer.thingId.male
            else
                outfitLookType = offer.thingId.female
            end
            if not outfitLookType then
                return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "This outfit seems not to suit your sex, we are sorry for that!")
            end
            player:addOutfitAddon(outfitLookType, offer.addon or 0)
            -- If offer is mount
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_MOUNT then
            player:addMount(offer.thingId)
            -- If offer is name change
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE then
            -- If player typed name yet!
            if productType == GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE then
                local newName = msg:getString()
                local resultId = db.storeQuery("SELECT * FROM `players` WHERE `name` = " .. db.escapeString(newName) .. "")
                if resultId ~= false then
                    return addPlayerEvent(sendStoreError, 650, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "This name is already used, please try again!")
                end
                local result = GameStore.canChangeToName(newName)
                if not result.ability then
                    return addPlayerEvent(sendStoreError, 650, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, result.reason)
                end
                newName = newName:lower():gsub("(%l)(%w*)", function(a, b) return string.upper(a) .. b end)
                db.asyncQuery("UPDATE `players` SET `name` = " .. db.escapeString(newName) .. " WHERE `id` = " .. player:getGuid())
                message =  "You have successfully changed you name, you must relog to see changes."
                -- If not, we ask him to do!
            else
                return addPlayerEvent(sendRequestPurchaseData, 250, player, offer.id, GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE)
            end
            -- If offer is sex change
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE then
            player:toggleSex()
            -- If offer is promotion
        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PROMOTION then
            if not GameStore.addPromotionToPlayer(player, offer.thingId) then
                return false
            end
            -- You can add whatever offer types to suit your needs!
        else
            -- ToDo :: implement purchase function
            return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "This offer is fake, please contact admin.")
        end
        -- Removing coins
        player:removeCoinsBalance(offer.price)
        -- We add this purchase to history!
        GameStore.insertHistory(player:getAccountId(), GameStore.HistoryTypes.HISTORY_TYPE_NONE, offerCountStr .. offer.name, offer.price * -1)
        -- Send to client that purchase is successful!
        return addPlayerEvent(sendStorePurchaseSuccessful, 650, player, message)
    end
    -- If we didn't found the offer or error happened
    addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_INFORMATION, "We couldn't locate this offer, please try again later.")
end
-- Both functions use same formula!
function parseOpenTransactionHistory(player, msg)
    local page = 1
    GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE = msg:getByte()
    sendStoreTransactionHistory(player, page, GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE)
end
function parseRequestTransactionHistory(player, msg)
    local page = msg:getU32()
    sendStoreTransactionHistory(player, page, GameStore.DefaultValues.DEFAULT_VALUE_ENTRIES_PER_PAGE)
end
--==Sending==--
function openStore(player)
    if not GameStore.Categories then
        return false
    end
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_OpenStore)
    msg:addByte(0x00)
    msg:addU16(#GameStore.Categories)
    for k, category in ipairs(GameStore.Categories) do
        msg:addString(category.name)
        msg:addString(category.description)
        if player:getClient().version >= 1093 then
            msg:addByte(category.state or GameStore.States.STATE_NONE)
        end
        msg:addByte(#category.icons)
        for m, icon in ipairs(category.icons) do
            msg:addString(icon)
        end
        msg:addString(category.parentCategory)
    end
    msg:sendToPlayer(player)
    sendCoinBalanceUpdating(player, true)
end
function sendShowStoreOffers(player, category)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_StoreOffers)
    msg:addString(category.name)
    msg:addU16(category.offers and #category.offers or 0x00)
    if category.offers then
        for k, offer in ipairs(category.offers) do
            msg:addU32(offer.id and offer.id or 0xFFFF) -- we later detect this number!
            local name = ""
            if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM and offer.count then
                name = offer.count .. "x "
            end
            if offer.type == GameStore.OfferTypes.OFFER_TYPE_STACKABLE and offer.count then
                name = offer.count .. "x "
            end
            name = name .. (offer.name or "Something Special")
            msg:addString(name)
            msg:addString(offer.description or GameStore.getDefaultDescription(offer.type))
            msg:addU32(offer.price and offer.price or 0xFFFF)
            msg:addByte(offer.state or GameStore.States.STATE_NONE) -- default is none
            local disabled, disabledReason = 0, ""
            if offer.disabled == true or not offer.type then
                disabled = 1
            end
            if offer.type ~= GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE and not offer.thingId then
                disabled = 1
            end
            if disabled == 1 and offer.disabledReason then -- dynamic disable
                disabledReason = offer.disabledReason
            end
            if disabled ~= 1 then
                if offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT or offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
                    local outfitLookType
                    if player:getSex() == PLAYERSEX_MALE then
                        outfitLookType = offer.thingId.male
                    else
                        outfitLookType = offer.thingId.female
                    end
                    if outfitLookType then
                        if offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT and player:hasOutfit(outfitLookType) then
                            disabled = 1
                            disabledReason = "You already have this outfit."
                        elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT_ADDON then
                            if player:hasOutfit(outfitLookType) then
                                if player:hasOutfit(outfitLookType, offer.addon) then
                                    disabled = 1
                                    disabledReason = "You already have this addon."
                                end
                            else
                                disabled = 1
                                disabledReason = "You don't have the outfit, you can't buy the addon."
                            end
                        end
                    else
                        disabled = 1
                        disabledReason = "The offer is fake."
                    end
                elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_MOUNT then
                    local hasMount = player:hasMount(offer.thingId)
                    if hasMount == true then
                        disabled = 1
                        disabledReason = "You already have this mount."
                    end
                elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PROMOTION then
                    if GameStore.canAddPromotionToPlayer(player, offer.thingId).ability == false then
                        disabled = 1
                        disabledReason = "You can't get this promotion"
                    end
                end
            end
            msg:addByte(disabled)
            if disabled == 1 and player:getClient().version >= 1093 then
                msg:addString(disabledReason)
            end
            msg:addByte(#offer.icons)
            for k, icon in ipairs(offer.icons) do
                msg:addString(icon)
            end
            msg:addU16(0) -- We still don't support SubOffers!
        end
    end
    msg:sendToPlayer(player)
end
function sendStoreTransactionHistory(player, page, entriesPerPage)
    local entries = GameStore.retrieveHistoryEntries(player:getAccountId()) -- this makes everything easy!
    if #entries == 0 then
        return addPlayerEvent(sendStoreError, 250, player, GameStore.StoreErrors.STORE_ERROR_HISTORY, "You don't have any entries yet.")
    end
    local toSkip = (page - 1) * entriesPerPage
    for i = 1, toSkip do
        table.remove(entries, 1) -- we remove first!
    end
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_OpenTransactionHistory)
    msg:addU32(page)
    msg:addU32(#entries > entriesPerPage and 0x01 or 0x00)
    msg:addByte(#entries >= entriesPerPage and entriesPerPage or #entries)
    for k, entry in ipairs(entries) do
        if k >= entriesPerPage then break end
        msg:addU32(entry.time)
        msg:addByte(entry.mode)
        msg:addU32(entry.amount)
        msg:addString(entry.description)
    end
    msg:sendToPlayer(player)
end
function sendStorePurchaseSuccessful(player, message)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_CompletePurchase)
    msg:addByte(0x00)
    msg:addString(message)
    msg:addU32(player:getCoinsBalance())
    msg:addU32(player:getCoinsBalance())
    msg:sendToPlayer(player)
end
function sendStoreError(player, errorType, message)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_StoreError)
    msg:addByte(errorType)
    msg:addString(message)
    msg:sendToPlayer(player)
end
function sendCoinBalanceUpdating(player, updating)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_CoinBalanceUpdating)
    msg:addByte(0x00)
    msg:sendToPlayer(player)
    if updating == true then
        sendUpdateCoinBalance(player)
    end
end
function sendUpdateCoinBalance(player)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_CoinBalanceUpdating)
    msg:addByte(0x01)
    msg:addByte(GameStore.SendingPackets.S_CoinBalance)
    msg:addByte(0x01)
    msg:addU32(player:getCoinsBalance())
    msg:addU32(player:getCoinsBalance())
    msg:sendToPlayer(player)
end
function sendRequestPurchaseData(player, offerId, type)
    local msg = NetworkMessage()
    msg:addByte(GameStore.SendingPackets.S_RequestPurchaseData)
    msg:addU32(offerId)
    msg:addByte(type)
    msg:sendToPlayer(player)
end
--==GameStoreFunctions==--
GameStore.getCategoryByName = function(name)
    for k, category in ipairs(GameStore.Categories) do
        if category.name:lower() == name:lower() then
            return category
        end
    end
    return nil
end
GameStore.getOfferById = function(id)
    for Cat_k, category in ipairs(GameStore.Categories) do
        if category.offers then
            for Off_k, offer in ipairs(category.offers) do
                if offer.id == id then
                    return offer
                end
            end
        end
    end
    return nil
end
GameStore.insertHistory = function(accountId, mode, description, amount)
    return db.asyncQuery(string.format("INSERT INTO `store_history`(`account_id`, `mode`, `description`, `coin_amount`, `time`) VALUES (%s, %s, %s, %s, %s)", accountId, mode, db.escapeString(description), amount, os.time()))
end
GameStore.retrieveHistoryEntries = function(accountId)
    local entries = {}
    local resultId = db.storeQuery("SELECT * FROM `store_history` WHERE `account_id` = " .. accountId .. " ORDER BY `time` DESC LIMIT 15;")
    if resultId ~= false then
        repeat
            local entry = {
                mode = result.getDataInt(resultId, "mode"),
                description = result.getDataString(resultId, "description"),
                amount = result.getDataInt(resultId, "coin_amount"),
                time = result.getDataInt(resultId, "time"),
            }
            table.insert(entries, entry)
        until not result.next(resultId)
        result.free(resultId)
    end
    return entries
end
GameStore.getDefaultDescription = function(offerType)
    local t, descList = GameStore.OfferTypes
    if offerType == t.OFFER_TYPE_OUTFIT or offerType == t.OFFER_TYPE_OUTFIT_ADDON then
        descList = GameStore.DefaultDescriptions.OUTFIT
    elseif offerType == t.OFFER_TYPE_MOUNT then
        descList = GameStore.DefaultDescriptions.MOUNT
    elseif offerType == t.OFFER_TYPE_NAMECHANGE then
        descList = GameStore.DefaultDescriptions.NAMECHANGE
    elseif offerType == t.OFFER_TYPE_SEXCHANGE then
        descList = GameStore.DefaultDescriptions.SEXCHANGE
    else
        return ""
    end
    return descList[math.floor(math.random(1, #descList))] or ""
end
GameStore.canChangeToName = function(name)
    local result = {
        ability = false
    }
    if name:len() < 3 or name:len() > 14 then
        result.reason = "Your new name's length should be lower than 3 or higher than 14."
        return result
    end
    -- just copied from znote aac.
    local words = {"owner", "gamemaster", "hoster", "admin", "staff", "tibia", "account", "god", "anal", "ass", "fuck", "sex", "hitler", "pussy", "dick", "rape", "cm", "gm", "tutor", "counsellor"}
    local split = name:split(" ")
    for k, word in ipairs(words) do
        for k, nameWord in ipairs(split) do
            if nameWord:lower() == word then
                result.reason = "You can't use word \"" .. word .. "\" in your new name."
                return result
            end
        end
    end
    if MonsterType(name) then
        result.reason = "Your new name \"" .. name .. "\" can't be a monster's name."
        return result
    elseif Npc(name) then
        result.reason = "Your new name \"" .. name .. "\" can't be a npc's name."
        return result
    end
    local letters = "{}|_*+-=<>0123456789@#%^&()/*\\.,:;~!\"$"
    for i = 1, letters:len() do
        local c = letters:sub(i, i)
        for i = 1, name:len() do
            local m = name:sub(i, i)
            if m == c then
                result.reason = "You can't use this letter \"" .. c .. "\" in your new name."
                return result
            end
        end
    end
    result.ability = true
    return result
end
GameStore.canAddPromotionToPlayer = function(player, promotion, send)
    local result = {
        ability = true
    }
    local vocation = player:getVocation()
    -- Working --
    local vocationCopy, baseVocation = vocation, vocation
    vocation = vocation:getDemotion()
    while vocation do
        baseVocation = vocation
        vocation = vocation:getDemotion()
    end
    local baseVocationsCount = GameStore.BaseVocationsCount or 4
    local newVocId = (baseVocationsCount * promotion) + baseVocation:getId()
    if not Vocation(newVocId) then
        if send then
            addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "The offer is fake, please report it!")
        end
        result.ability = false
        return result
    end
    -- If promotion is less than player's voc, or player don't have previous promotion
    if newVocId <= vocationCopy:getId() then
        if send then
            addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You already have this promotion!")
        end
        result.ability = false
        return result
    end
    if (newVocId - baseVocationsCount) ~= vocationCopy:getId() then
        if send then
            addPlayerEvent(sendStoreError, 350, player, GameStore.StoreErrors.STORE_ERROR_NETWORK, "You need higher promotion to get his one.")
        end
        result.ability = false
        return result
    end
    result.vocId = newVocId
    return result
end
GameStore.addPromotionToPlayer = function(player, promotion)
    local result = GameStore.canAddPromotionToPlayer(player, promotion, true)
    if result.ability == false then return false end
    local basics = {
        health = 185,
        mana = 40,
        cap = 500
    }
    player:setVocation(result.vocId)
    local newVoc = player:getVocation()
    player:setMaxHealth(basics.health + (newVoc:getHealthGain() * player:getLevel()))
    player:setMaxMana(basics.mana + (newVoc:getManaGain() * player:getLevel()))
    player:setCapacity(basics.cap + (newVoc:getCapacityGain() * player:getLevel()))
    player:addHealth(player:getMaxHealth())
    player:addMana(player:getMaxMana())
    player:sendTextMessage(MESSAGE_INFO_DESCR, "You have been promoted to " .. newVoc:getName())
    return true
end
--==Player==--
function Player.getCoinsBalance(self)
    resultId = db.storeQuery("SELECT `coins` FROM `accounts` WHERE `id` = " .. self:getAccountId())
    if not resultId then return 0 end
    return result.getDataInt(resultId, "coins")
end
function Player.setCoinsBalance(self, coins)
    db.asyncQuery("UPDATE `accounts` SET `coins` = " .. coins .. " WHERE `id` = " .. self:getAccountId())
    return true
end
function Player.canRemoveCoins(self, coins)
    if self:getCoinsBalance() < coins then
        return false
    end
    return true
end
function Player.removeCoinsBalance(self, coins)
    if self:canRemoveCoins(coins) then
        return self:setCoinsBalance(self:getCoinsBalance() - coins)
    end
    return false
end
function Player.addCoinsBalance(self, coins, update)
    self:setCoinsBalance(self:getCoinsBalance() + coins)
    if update then sendCoinBalanceUpdating(self, true) end
    return true
end
function Player.toggleSex(self)
    local currentSex = self:getSex()
    local playerOutfit = self:getOutfit()
    if currentSex == PLAYERSEX_FEMALE then
        self:setSex(PLAYERSEX_MALE)
        playerOutfit.lookType = 128
    else
        self:setSex(PLAYERSEX_FEMALE)
        playerOutfit.lookType = 136
    end
    self:setOutfit(playerOutfit)
end

Pois estava pegando premium_points ao invés de coins. Parabéns @malucooo, excelente trabalho.

 

tá atualizado no github... agora basta listar mais bugs que vamos removendo!

 

 

O melhor conteúdo da atualidade!

http://www.gitlab.com/malucooo/otxserver-new/

- Full Global Map with 12.xx updates, all quests and many features!

- Protocol 12.31

Link para o post
Compartilhar em outros sites
6 horas atrás, schiavo01 disse:

Em Roshamuul, você da use nos pilar para virar BONES ou BIxo -  Não acontece nada?

Como Resolver?
01:16 You see a large pile of various bones.

é verdade, tá sem action, deveria dar cluster ou sumonar Guzzlemaw né?

CONHEÇA MEU PROJETO:

WWW.ETERNUS-GLOBAL.COM

 

tibia-logo.gif

Link para o post
Compartilhar em outros sites
  • Erimyth pinned this tópico
  • Erimyth featured this tópico
  • Erimyth unfeatured e unpinned this tópico

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.


  • Conteúdo Similar

    • Por Johncore
      Olá galera, é com muita dedicação que trago para este forum uma exclusividade que só eu tinha.
      Mapa Dragonsouls 11x 99%, tem alguns detalhes de sqm ou borda que você possa precisar fazer,
      Dragonsouls é um servidor ATS Custom, baseado em senhor dos aneis. via muita gente perguntando por esse mapa e eu tinha a muitos anos, resolvi converter.
      mas ele está 99% pronto para uso.
       
      Esse mapa é 100% compativel para rodar na Datapack Otg Server 11,
      Otg Server é um projeto que trabalha com varias datapacks de tibia rl e ATS Custom.
       
      Github:
      https://github.com/otg-br/
       
      Participe do grupo Otg Server:  
      https://chat.whatsapp.com/EWV3dVvS6nt1em7q23FGu7
       
       
      MAPA:
       
      INICIAL ISLAND

       
      CARLIN

       
      CIDADE TIRITH

       
      CIDADE BREE

       
       
       
       
      world.zip
    • Por Johncore
      Olá pessoas, estou disponibilizando aqui mais uma exclusividade que é o Mapa Evolunia, ele é baseado no servidor Evolunia.net
       
      Esse mapa é 100% compativel para rodar na Datapack Otg Server 11x,
      Otg Server é um projeto que trabalha com varias datapacks de tibia rl e ATS Custom.
       
      Participe do grupo Otg Server:  
      https://chat.whatsapp.com/EWV3dVvS6nt1em7q23FGu7
       
      Creditos:
      evolunia
      world.zip
    • Por Johncore
      Otg Server é um projeto fork do The Forgotten Server 1.3, feito por brasileiros que visam sempre por estabilidade, um código mais clean, temos no projeto várias Datapacks como
      Global 11.0, Global 8.6, Global 8.0, RadBR 11.0, Evolutions 11.0, Yurots Classic 11.0, nossa base também é excelente para rodar projetos que são mapa Baiak ou ATS Custom pelo baixissimo uso de cpu e fix do Decay de itens.

      Todos são bem vindos para colaborar com o projeto... que não visa nenhum lucro financeiro, queremos apenas colaborar com a comunidade OTSERV,
      temos ouvido de muitas pessoas que procuram uma base estável, limpa, esse é o nosso objetivo nesse projeto.
       
      Estamos a procura de programadores/dev/webmaster que queiram ajudar / que tenham tempo e serão recompensados por isso.
       
      Nossa Datapack principal Global 11.00 contem as seguintes features:
      CAST SYSTEM ✅
      AUTOLOOT ✅
      WINTER UPDATE 2023 ✅
      SUMMER UPDATE 2023 ✅
      ADDONS 13.22 UPDATE ✅
      MONTARIAS 13.22 UPDATE ✅
      ITEMS 13.22 UPDATE ✅
      DAILY REWARD ✅
      IMBUEMENTS ✅
      PREY ✅
      EXERCISE WEAPONS ✅
      HIRELINGS NPCS ✅
      ANTI ROLLBACK ✅
       
       
      Github Global 11x:  💾
      https://github.com/otg-br/global-11x
      Clients e outras ferramentas:  💾
      https://github.com/otg-br/tools
      Github Otg Gesior:  💾
      https://github.com/otg-br/gesior
      Github Otg Otclientv8:  💾
      https://github.com/otg-br/otclientv8
      Wiki Otg:  💾
      https://github.com/otg-br/global-11x/wiki
       
       
      Creditos:
      TFS Team Erick Nunes Gui Bruxo Worthdavi LuSKT Leo Pereira Luan Luciano Cjaker Comedinhas Nekiro OTG Colaborators
    • Por Dnzk21
      COMO POSSO IMPORTAR UMA CITY EMCIMA DE OUTRA CITY SEM PERDER AS HOUSES
      ALGUEM PODE M,E AJUDAR 
      E A MESMA CITY MJAIS QUANDO IMPORTO PERDE TODAS CASAS QUANDO SALVA E ABRE O SERVIDOR
    • Por Johncore
      Arcadia é uma cidade custom bem bonita que pode ser encontrada no servidor AureraGlobal,
      Por ter esse conteudo aqui em primeira mão, resolvi disponibilizar para a comunidade.
       


       
      Creditos:
      Aurera Team
      Johncorex
      Arcadia-spawn.xml Arcadia-house.xml Arcadia.otbm

×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo