Ir para conteúdo

BrunoWots

Membro
  • Registro em

  • Última visita

Histórico de Curtidas

  1. Gostei
    BrunoWots deu reputação a xandro em Sprites Return Of The Saiyans   
    pensando assim, não existiria esse forum, pois o tibia e outros derivados foram investido tempo e grana tbm
  2. Curtir
    BrunoWots deu reputação a jotape1322 em (Resolvido)exercise dummy   
    .Qual servidor ou website você utiliza como base? 
    1.3
    Qual o motivo deste tópico? 
    seguinte, o script ta funcionando lindo e perfeito, exceto quando eu estou treinando e deslogo o char sem parar de treinar, ai quando eu relogo o char ele fala pra mim que eu já estou treinando daí não consigo treinar mais, sei que tem algo a ver com o storage do player que ta setado como treinando preciso que quando ele deslogue ele mude esse storage
    Está surgindo algum erro? Se sim coloque-o aqui. 
     
    Você tem o código disponível? Se tiver publique-o aqui: 
    local skills = { [32384] = {id=SKILL_SWORD,voc=4}, -- KNIGHT [32385] = {id=SKILL_AXE,voc=4}, -- KNIGHT [32386] = {id=SKILL_CLUB,voc=4}, -- KNIGHT [32387] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW}, -- PALADIN [32388] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_SMALLICE}, -- DRUID [32389] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE}, -- SORCERER [32124] = {id=SKILL_SWORD,voc=4}, -- KNIGHT [32125] = {id=SKILL_AXE,voc=4}, -- KNIGHT [32126] = {id=SKILL_CLUB,voc=4}, -- KNIGHT [32127] = {id=SKILL_DISTANCE,voc=3,range=CONST_ANI_SIMPLEARROW}, -- PALADIN [32128] = {id=SKILL_MAGLEVEL,voc=2,range=CONST_ANI_SMALLICE}, -- DRUID [32129] = {id=SKILL_MAGLEVEL,voc=1,range=CONST_ANI_FIRE} -- SORCERER } local houseDummies = {32143, 32144, 32145, 32146, 32147, 32148} local freeDummies = {32142, 32149} local skillRateDefault = configManager.getNumber(configKeys.RATE_SKILL) local magicRateDefault = configManager.getNumber(configKeys.RATE_MAGIC) local function removeExerciseWeapon(player, exercise) exercise:remove(1) player:sendTextMessage(MESSAGE_INFO_DESCR, "Your training weapon vanished.") stopEvent(training) player:setStorageValue(Storage.isTraining,0) end local function start_train(pid,start_pos,itemid,fpos, bonusDummy, dummyId) local player = Player(pid) if player ~= nil then if Tile(fpos):getItemById(dummyId) then local pos_n = player:getPosition() if start_pos:getDistance(pos_n) == 0 and getTilePzInfo(pos_n) then if player:getItemCount(itemid) >= 1 then local exercise = player:getItemById(itemid,true) if exercise:isItem() then if exercise:hasAttribute(ITEM_ATTRIBUTE_CHARGES) then local charges_n = exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES) if charges_n >= 1 then exercise:setAttribute(ITEM_ATTRIBUTE_CHARGES,(charges_n-1)) local voc = player:getVocation() if skills[itemid].id == SKILL_MAGLEVEL then local magicRate = getRateFromTable(magicLevelStages, player:getMagicLevel(), magicRateDefault) if not bonusDummy then player:addManaSpent(math.ceil(500*magicRate)) else player:addManaSpent(math.ceil(500*magicRate)*1.1) -- 10% end else local skillRate = getRateFromTable(skillsStages, player:getEffectiveSkillLevel(skills[itemid].id), skillRateDefault) if not bonusDummy then player:addSkillTries(skills[itemid].id, 7*skillRate) else player:addSkillTries(skills[itemid].id, (7*skillRate)*1.1) -- 10% end end fpos:sendMagicEffect(CONST_ME_HITAREA) if skills[itemid].range then pos_n:sendDistanceEffect(fpos, skills[itemid].range) end if exercise:getAttribute(ITEM_ATTRIBUTE_CHARGES) == 0 then removeExerciseWeapon(player, exercise) else local training = addEvent(start_train, voc:getAttackSpeed(), pid,start_pos,itemid,fpos,bonusDummy,dummyId) player:setStorageValue(Storage.isTraining,1) end else removeExerciseWeapon(player, exercise) end end end end else player:sendTextMessage(MESSAGE_INFO_DESCR, "Your training has stopped.") stopEvent(training) player:setStorageValue(Storage.isTraining,0) end else stopEvent(training) player:sendTextMessage(MESSAGE_INFO_DESCR, "Your training has stopped.") player:setStorageValue(Storage.isTraining, 0) end else stopEvent(training) if player then player:sendTextMessage(MESSAGE_INFO_DESCR, "Your training has stopped.") player:setStorageValue(Storage.isTraining,0) end end return true end function onUse(player, item, fromPosition, target, toPosition, isHotkey) local start_pos = player:getPosition() if player:getStorageValue(Storage.isTraining) == 1 then player:sendTextMessage(MESSAGE_INFO_DESCR, "You are already training.") return false end if target:isItem() then if isInArray(houseDummies,target:getId()) then if not skills[item.itemid].range and (start_pos:getDistance(target:getPosition()) > 1) then player:sendTextMessage(MESSAGE_INFO_DESCR, "Get closer to the dummy.") stopEvent(training) return true end player:sendTextMessage(MESSAGE_INFO_DESCR, "You started training.") start_train(player:getId(),start_pos,item.itemid,target:getPosition(), true, target:getId()) elseif isInArray(freeDummies, target:getId()) then if not skills[item.itemid].range and (start_pos:getDistance(target:getPosition()) > 1) then player:sendTextMessage(MESSAGE_INFO_DESCR, "Get closer to the dummy.") stopEvent(training) return true end player:sendTextMessage(MESSAGE_INFO_DESCR, "You started training.") start_train(player:getId(),start_pos,item.itemid,target:getPosition(), false, target:getId()) end end return true end    
    Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 

     
    sendo que ele não está treinando
    resolvido, em login lua na function onlogin adicionei
            player:setStorageValue(Storage.isTraining,0)
    e toda vez que ele loga ele seta o storage do trainer pra 0
  3. Curtir
    BrunoWots deu reputação a Nolangg em Baiak Hyper [8.60][TFS 0.3] ~ King-Baiak (atualizado 20/03/23)   
    Olá Tibianos.
    Hoje após um looooongo tempo sem tempo e animo pra mexer em server etc etc.
    Venho trazer a vós um servidor do @Igorzerah  que foi vendido à mim, e foi feito inúmeras modificações também.
    Sem mais enrolação...
     
    O  que você irá encontrar no servidor?
     
    Sistema de Montaria (desativado) pelo comando "!mount" (dá pra comprar no site)
    Sistema de Daily Monster (toda vez que abre a distro um monstro é selecionado *também configurável)
    Sistema de Castle48/24HRS (exatamente as 21:00H o castle 48h abre todos os dias, já o castle 24h é sempre aberto a invasões e tem monstros específicos lá)
    Sistema de Cast Arrows / Spy System (spy é um cast para admins que mesmo sem estar ativado ele consegue ver *usado para monitorar players)
    Sistema de EXP FOOD / EGGS (dá pra usar simultâneos ovos de EXP, assim aumentando *ex: 100% + 200% + 300% etc etc)
    Sistema de Anti Divulgação  (Anti divulgação modificado, intruso parece que está divulgando mas não está, tipo um fakechat...)
    Sistema de Roleta (uma roleta que pode dar itens temporarios *itens hyper)
    Sistema de Mineração (sistema básico que dá pepitas de ouro *usado no lugar do money para comprar coisas)
    Várias Cidades (Baiak City, Nether, Oramond e Roshamuul)
    Boss Gaz'Haragoth e Boss CLAPTOMANIACO (um por boss token e outro por horário)
    Fast Respawn (quanto mais jogadores online mais rápido é o spawn)
     
    esse é o resumo do servidor, eu trabalhei mudando a maioria das coisas e tirando vários bugs, mas, o @nettonnwk vendeu o servidor e me desanimou
    agora eu estou disponibilizando, já que também teve trabalho meu aqui ?
    um monte de bug foi resolvido, mas ainda pode ter mais (falta de foco por minha parte dhasudhsa)
     
    *algumas imagens do servidor:
     

     

     

     
     

     

     
    Link Download Baiak Hyper
    https://www.mediafire.com/file/p9hdkethf6hjrbr/baiakhyper.zip/file
    Link Scan Servidor Baiak Hyper
    https://www.virustotal.com/gui/file/2993b94b808c8c5a98eca8139bd4ab4745ea482e603b847e02464e16458382b5?nocache=1
    Client 8.60 Extendido Hyper
    https://www.mediafire.com/file/l7mkxe4zmb2nlzv/Starlix+8.60.zip/file
    Link Scan Client 8.60
    https://www.virustotal.com/gui/file/11a9444677731e0f2620ce75a159b84aad21ceed472ca68f0da10ee41b8283be
    Client 8.60 Mobile Hyper
    https://www.mediafire.com/file/3vvqy78h5b5ccpr/starlix-mobile.apk/file
    Link Scan Mobile 8.60
    https://www.virustotal.com/gui/file/3ec7b021990501eacf208452296025b7b3e02a5c1c8a27e012dc77b06132c6c1?nocache=1
    Otclient v8 Hyper
    https://www.mediafire.com/file/ao7mbah1odhm4mk/Otclient-Starlix.zip/file
    Link Scan Otclient V8
    https://www.virustotal.com/gui/file/b703dac28286dd6139b2f140516b6dfe9882a288b2909817d1570692e73e3c04?nocache=1
     
    Source OTX 2.15 (Modificada por mim e feita algumas alterações..; darei suporte mas... be patienty;)
     
    https://www.mediafire.com/file/vacu76zusyk4ubr/king.rar/file
    scan: https://www.virustotal.com/gui/file/2a5cbca6a6acc028c9809448151836e68250f49abbc7e804a696e2a7eb1dac6f?nocache=1
     
     
    Atualização:
    Site: https://drive.google.com/file/d/1zCZAVvacHInGpUOWc82hrsPDGpZ2ro8l/view?usp=share_link
    Scan Site: https://www.virustotal.com/gui/url/dc2516f12b7f1bb6e3a265fd6a67a4f200fef3664c1ac3d2554203d78690dfb0?nocache=1
     
    Imagem do Site:
     

     
    apesar da maioria das coisas serem feitas por várias pessoas, o site os créditos de alterações é todo meu (já a base é crédito totalmente ao gesior )
     
     
    db compativel com o site:
    baiak.sql
     
    descrição quando estava sendo vendido*
     
    ⭐️ SERVIDOR 8.60 COM RESETS, MONTARIAS E GOLDEN OUTFIT ⭐️
    INFORMAÇÕES BÁSICAS DO SERVIDOR:
    [+] MAPA BAIAK
    [+] HIGH EXP
    [+] RESETS COM + DAMAGE
    [+] PROTEÇÃO DE BAN DO OTSERVLIST
    [+] ANTI-LAG DE TALKACTION
    [+] DISTRO OTIMIZADA
    [+] SOURCE PRONTA PARA WINDOWS/LINUX
    [+] SITE ATUAL E CONFIGURADO
    [+] CLIENTE PRÓPRIO + DB LIMPA
    ? SISTEMAS ATUAIS ?
    [+] AUTOLOOT AUTOMÁTICO
    [+] CITY DONATE
    [+] ROSHAMUUL, ORAMOND E NETHER
    [+] MONTARIAS E GOLDEN OUTFIT
    [+] INVASÃO DE MONSTROS AUTOMÁTICAS
    [+] DAILY MONSTER QUE APARECE AO LOGAR
    [+] MONTARIAS COM COMANDO !MOUNT
    [+] SISTEMA DE ROLETA ATUAL
    [+] CAST WATCH
    [+] FAST ATTACK
    [+] CAST ARROWS
    [+] PUSH CRUZADO
    [+] REWARD CHEST
    [+] WARSQUARE
    [+] COMBO EXP DE POTIONS
    [+] MINERAÇÃO COM LOJA
    [+] SISTEMA DE BOSS
    [+] CRITICAL/DODGE [500/500]
    [+] LIFE E MANA EM PORCENTAGEM*
    [+] VARIAS QUESTS
    ? EVENTOS ?
    [+] EVENTO DTT (AUTOMÁTICO)
    [+] EVENTO BATLEFIELD (AUTOMÁTICO)
    [+] EVENTO SNOWBALLWAR (AUTOMÁTICO)
    [+] EVENTO DESERT WAR (AUTOMÁTICO)
    [+] EVENTO ZOMBIE (AUTOMÁTICO)
    [+] EVENTO CAMPO MINADO (AUTOMÁTICO)
    [+] EVENTO TEAM BATLE (AUTOMÁTICO)
    [+] EVENTO CAPTURE THE FLAG (AUTOMÁTICO)
     
    see ya l8 guys.
     
    créditos em modificações do servidor ( @Lyu, @Diiego Liima, eu, @nettonnwk e o @Igorzerah)
     
    Nós somos aquilo que fazemos repetidamente. Excelência, não é um modo de agir, mas um hábito.
  4. Curtir
    BrunoWots deu reputação a Qwizer em MercadoPago Retorno automatico (PIX)   
    MercadoPago Retorno automatico (PIX)
     
    Abaixo Segue código PHP de pagamento via pix pelo mercado pago com retorno para quem quiser adaptar em seus sites ter uma direção de onde ir 
    testado em Znote e MyAcc.
     

     
    pix.zip
     
    https://mega.nz/folder/m4QkWBLS#PIvJ_scVm7w8-5FLlStTHg  
  5. Curtir
    BrunoWots recebeu reputação de fabiopython em [Legacy SRC]Global Full 7.6, 7.7 e 7.4 sqlite acc 1/1   
    ⚫ Olá, venho aqui trazer um global (servfull 7.60 e 7.72 cipsoft) também roda 7.4, download junto com a distro compilada de graça, roda em sqlite, é só abrir e rodar o ot !!!!
     
     
                             Senha do account name é 1/1                          
                            senha do god é 111111/222222                         
    RealOTS
    ✔️-Tasks system 100%
    ✔️-CipSoft Engine
    ✔️-All Quests 100%
    ✔️-All NPCs 100%
    ✔️-Real Monsters 100%
    ✔️-Caves 100%
    ✔️-Real Damage 7.6
    ✔️-Trainer off
    ✔️-Mensage loot
    ✔️-Shared Experience
    ✔️-Poi + Acess 100%
    ✔️-Houses 100%
    ✔️-Livros e histórias 100%
    ✔️-Command /buy, !buy.
     
    ⚡ -Items old
    ⚡ - Monstros e Outfits
     
     
    ⚫ Algumas imagens do server, quests e hunts.
     
     
     
     
    ⚫ Downalod e Scamm:
    https://goo.gl/ztc2nP
    https://goo.gl/N52pP2
     
    Atualização:
    * Treiner offline adicionado no templo de thais junto com o npc de task Oldman.

    *Acesso rápido a poi depois de terminar a segunda sala pelo teleport, caso você morra.

  6. Curtir
    BrunoWots recebeu reputação de haszoniuspl em [Legacy SRC]Global Full 7.6, 7.7 e 7.4 sqlite acc 1/1   
    ⚫ Olá, venho aqui trazer um global (servfull 7.60 e 7.72 cipsoft) também roda 7.4, download junto com a distro compilada de graça, roda em sqlite, é só abrir e rodar o ot !!!!
     
     
                             Senha do account name é 1/1                          
                            senha do god é 111111/222222                         
    RealOTS
    ✔️-Tasks system 100%
    ✔️-CipSoft Engine
    ✔️-All Quests 100%
    ✔️-All NPCs 100%
    ✔️-Real Monsters 100%
    ✔️-Caves 100%
    ✔️-Real Damage 7.6
    ✔️-Trainer off
    ✔️-Mensage loot
    ✔️-Shared Experience
    ✔️-Poi + Acess 100%
    ✔️-Houses 100%
    ✔️-Livros e histórias 100%
    ✔️-Command /buy, !buy.
     
    ⚡ -Items old
    ⚡ - Monstros e Outfits
     
     
    ⚫ Algumas imagens do server, quests e hunts.
     
     
     
     
    ⚫ Downalod e Scamm:
    https://goo.gl/ztc2nP
    https://goo.gl/N52pP2
     
    Atualização:
    * Treiner offline adicionado no templo de thais junto com o npc de task Oldman.

    *Acesso rápido a poi depois de terminar a segunda sala pelo teleport, caso você morra.

  7. Curtir
    BrunoWots recebeu reputação de Aletakashii em [Legacy SRC]Global Full 7.6, 7.7 e 7.4 sqlite acc 1/1   
    ⚫ Olá, venho aqui trazer um global (servfull 7.60 e 7.72 cipsoft) também roda 7.4, download junto com a distro compilada de graça, roda em sqlite, é só abrir e rodar o ot !!!!
     
     
                             Senha do account name é 1/1                          
                            senha do god é 111111/222222                         
    RealOTS
    ✔️-Tasks system 100%
    ✔️-CipSoft Engine
    ✔️-All Quests 100%
    ✔️-All NPCs 100%
    ✔️-Real Monsters 100%
    ✔️-Caves 100%
    ✔️-Real Damage 7.6
    ✔️-Trainer off
    ✔️-Mensage loot
    ✔️-Shared Experience
    ✔️-Poi + Acess 100%
    ✔️-Houses 100%
    ✔️-Livros e histórias 100%
    ✔️-Command /buy, !buy.
     
    ⚡ -Items old
    ⚡ - Monstros e Outfits
     
     
    ⚫ Algumas imagens do server, quests e hunts.
     
     
     
     
    ⚫ Downalod e Scamm:
    https://goo.gl/ztc2nP
    https://goo.gl/N52pP2
     
    Atualização:
    * Treiner offline adicionado no templo de thais junto com o npc de task Oldman.

    *Acesso rápido a poi depois de terminar a segunda sala pelo teleport, caso você morra.

  8. Curtir
    BrunoWots recebeu reputação de danieltrucudis em [Legacy SRC]Global Full 7.6, 7.7 e 7.4 sqlite acc 1/1   
    ⚫ Olá, venho aqui trazer um global (servfull 7.60 e 7.72 cipsoft) também roda 7.4, download junto com a distro compilada de graça, roda em sqlite, é só abrir e rodar o ot !!!!
     
     
                             Senha do account name é 1/1                          
                            senha do god é 111111/222222                         
    RealOTS
    ✔️-Tasks system 100%
    ✔️-CipSoft Engine
    ✔️-All Quests 100%
    ✔️-All NPCs 100%
    ✔️-Real Monsters 100%
    ✔️-Caves 100%
    ✔️-Real Damage 7.6
    ✔️-Trainer off
    ✔️-Mensage loot
    ✔️-Shared Experience
    ✔️-Poi + Acess 100%
    ✔️-Houses 100%
    ✔️-Livros e histórias 100%
    ✔️-Command /buy, !buy.
     
    ⚡ -Items old
    ⚡ - Monstros e Outfits
     
     
    ⚫ Algumas imagens do server, quests e hunts.
     
     
     
     
    ⚫ Downalod e Scamm:
    https://goo.gl/ztc2nP
    https://goo.gl/N52pP2
     
    Atualização:
    * Treiner offline adicionado no templo de thais junto com o npc de task Oldman.

    *Acesso rápido a poi depois de terminar a segunda sala pelo teleport, caso você morra.

  9. Curtir
    BrunoWots recebeu reputação de danieltrucudis em [Legacy SRC]Global Full 7.6, 7.7 e 7.4 sqlite acc 1/1   
    Não está com vírus, eu só compilei a source pra quem não sabe compilar, pega as source e compile você mesmo...
  10. Curtir
    Olá comunidade, venho aqui hoje trazer um autêntico servidor de mapa real full 8.0 completo. Talvez esse seja um dos servidores mais raro e pedido postado de graça em qualquer comunidade tendo em vista que esse servidor pode ser avaliado em no mínimo 200$ Dólares. Sem contar que é um dos servidores mais querido da comunidade tibiana como por exemplo o kasteria e realera.
     
     
          -Servidor compatível com cliente 8.0 cipsoft original sem customização.
          Características:
    Quests 100% Mapa 100% Missões 100% Creaturas 100% NPC'S 100% Houses 100% Raids 100%  
    Quests do servidor:
     
     
     
          Características detalhadas:
          » Todas as quests/missões/tasks/questlong/acessos 8.0.
          » Todas as ilhas: Port Hope, Liberty Bay, Rookgaard e Svargrond.
          » Vocações balanceadas, danos de feitiços de 8.0/7.6 foram levemente ajustados para melhor.
          » Raid System: Todas as invasões que existiam antigamente estão aqui.
          » Todos os monstros balanceados.
          » Addons podem ser obtidos como tíbia real. Ao fazer missões e coletar os itens! Outras características!
          » As criaturas boss do Sistema do Raid executarão uma incursão em uma cidade ou vila próxima.
          » Quest da Spike Sword adicionada em Rookgaard!
     
          Recursos opcionais:
          » Teleport Trainer Dummy igual ao Kasteria.
          » Npc Casino no depósito de Thais.
          » Npc's Dijinn's em Thais.
          » Runas à venda em npc's
          » Raid player summon um poderoso mago "Lord'Paulistinha". xD
     
     
    Download:
    Scan: Link
     
          Imagens:
    .
    global_8.0.rar
  11. Gostei
    BrunoWots deu reputação a JhonatanCWest em [Tutorial] Explicando e Criando Vocações   
    Olá TibiaKing,

    Vi muitas pessoas com dúvidas, mesmo contendo tutoriais, não entendiam,então tentarei fazer um bom tutorial.

    Ok, vamos por a mão na massa!

    Basicamente nós nos basearemos nisso:
    Localizado em: DATA/XML/VOCATION.XML

    Exemplo


    Primeiro vou explicar cada item pra você criar sua vocação certinha!

    id = não deve haver nenhuma igual, tente seguir a sequencia para não se perder.
    name = nome da nova vocação.
    description = quando der look aparecera esse nome, e caso acc manager também.
    needpremium = se precisa de premmium para ter essa vocação (0 = não 1 = sim)
    gaincap = o tanto de cap que vai ganhar quando upar
    gainhp = o tanto de vida que vai ganhar quando upar
    gainmana = o tanto de mana que vai ganhar quando upar
    gainhpticks = o tanto de segundos que demora pra subir a vida
    gainhpamount = o tanto de vida que vai ganhar a cada ( no nosso exemplo 6 ) segundos
    gainmanaticks = o tanto de segundos que demora pra subir a mana
    gainmanaamount = o tanto de mana que vai ganhar a cada ( no nosso exemplo 3 ) segundos
    manamultiplier = quanto ml vai demorar pra subir, quanto menor mais rápido
    attackspeed = velocidade do ataque de wands e weapons (quanto menor mais rápido)
    soulmax = o maximo de soul
    gainsoulticks = o tanto de segundos que vai demorar pra subir o soul
    fromvoc = como ele será reconhecido nos scripts ( bote igual o id )

    Formulas:

    meleeDamage = quanto hita com weapons ( exceto wands e rods )
    distDamage = quanto hita com ataques a distancia
    wandDamage = quando hita com wand
    magDamage = quando hita com magias
    magHealingDamage = quanto heala com magias de cura, ( tanto exura como exura sio )
    defense = quanto defende com escudos
    armor = quanto defende com armaduras

    Skill Ids:

    (0) Fist
    (1) Club
    (2) Sword
    (3) Axe
    (4) Distance
    (5) Shield
    (6) Fishing

    PS: Quando menor o skill multiplier, mais rápido upa os skills.

    Criando nova vocação :
    1. Basta você adicionar nosso exemplo, embaixo das vocations.

    Exemplo



    Adicionando Spells às novas vocações
    2. Basta adicionar o nome da nova vocação em: data/spells/spells.xml

    Exemplo



    Tutorial criado por mim, exceto a parte dos Skill_ids, que peguei de outros tutos.
    Pronto, espero ter ajudado.
    Se gostaram agradeçam por favor.
    Obrigado, JhonatanCWest
  12. Curtir
    BrunoWots deu reputação a Stew24 em [OTServBrGlobal 12.72] Big Training Area   
    Hey guys! sorry for not talking in portuguese 
    Since i won't use anymore this Training spots im going to release it for free.
    It uses OTBR 12.72 items.otb and its needed in order to work in OtservBRGlobal.
    ALL the training teleport leads to THAIS (So this to avoid spending time adding manually the teleports).
    Also you need to add your OWN training monks since i use my own monster file.
    Size of the map: 139Kb
    Version: 12.72 (OTBR .otb)
    Autor: Stewart
    Creditos: Stewart
    Trainers 12.72 by Stewart.zip
  13. Gostei
    BrunoWots deu reputação a Wakon em Modificar Client, Ajuda!   
    A única maneira de customizar o client do Tibia é editando pelo Hex Editor, creio eu.
    Para isso você pode utilizar o XVI32: 
    http://www.handshake.de/user/chmaas/delphi/download/xvi32.zip
     
    1 - Abra o XVI32, clique em File/Open... e selecione o executável do Tibia.
    2 - Aperte CTRL + F, selecione Text String e coloque o que você quer editar ( Exemplo: Magic Level )
    3 - Ai quando encontrar você tem que substituir as letras (Exemplo: Magia Level), para apagar o Level você deve apertar espaço, ou trocar o valor da esquerda na tabela de Hexadecimal por 00.
     
    Cuidados:
    Não pode deletar NADA, absolutamente NADA, se você apertar backspace e deletar algum character, vai bugar e o cliente não vai abrir mais!
    Você só pode substituir as letras, não pode dar um tamanho a mais, como não pode deletar não pode aumentar também!
    Exemplo: Magic Level para Magia do Personagem, vai bugar o cliente!
     
    É isso, tem um Tibia 8.60 meu que eu traduzi, se quiser tirar algumas ideias, apesar que as novas versões tem certas limitações se não me engano!
    http://www.tibiaking.com/forum/topic/51473-cliente-860-traduzido/
  14. Gostei
    BrunoWots deu reputação a runeraserver em Custom Cliente - Todas as versões - Qualquer IP   
    Fala galera,

    Vejo muita gente com dúvida de como fazer custom clients. Neste tutorial vou ensinar para vocês criar custom clients de todas as versões e com qualquer ip.

    1º Passo:
    • Baixe o programa NotePad http://notepad-plus-plus.org/repository/6.x/6.7.5/npp.6.7.5.Installer.exe

    2º Passo:
    • Vá no diretório onde está instalado o client que deseja editar, clique com o direito em Tibia.exe e selecione "Edit with Notepad++"

    3º Passo:
    • Pressione ctrl + f e busque por login01.tibia.com e substitua pelo seu ip, (exemplo.com.br).
    Perceba que login01.tibia.com + os 3 NUL que aparecem, somam 20 caracteres (NUL conta como 1).
    O seu IP deverá conter 20 caracteres ou menos.
    Exemplo:
    exemplo.com.br possui 14 caracteres
    Como o meu exemplo possui 14 caracteres e login01.tibia.comNULNULNUL possui 20, vou ter que preencher esses 6 caracteres que faltam com 6 NUL.
    Para isso, você deverá deixar o cursos de texto na frente do seu ip (exemplo.com.br"AQUI") e ir para Plugins>Converter>Conversion.


     
    Digite 0 em decimal e clique em (ASCII: Insert) 6 vezes, devendo ficar assim: exemplo.com.brNULNULNULNULNULNUL (Lembrando que acrescenta 6 NUL no caso do exemplo, o seu IP deverá completar os 20 caracteres podendo haver mais ou menos NULs).



    Procure por esses ips e faça os passos acima em todos:
    login01.tibia.com login02.tibia.com login03.tibia.com login04.tibia.com login05.tibia.com tibia01.cipsoft.com tibia02.cipsoft.com tibia03.cipsoft.com tibia04.cipsoft.com tibia05.cipsoft.com Feito isso, procure por:
    132127743205872284062295099082293384952776326496165507967876361843343953435544496682053323833394351797728954155097012103928360786959821132214473291575712138800495033169914814069637740318278150290733684032524174782740134357629699062987023311132821016569775488792221429527047321331896351555606801473202394175817 Substitue por:
    109120132967399429278860960508995541528237502902798129123468757937266291492576446330739696001110603907230888610072655818825358503429057592827629436413108566029093628212635953836686562675849720620786279431090218017681061521755056710823876476444260558147179707119674283982419152118103759076030616683978566631413 Créditos: Gesior
  15. Curtir
    Se caso tiver algum bug sim.
  16. Obrigado
    Update, servidor atualizado com a correção de alguns bugs que passaram despercebidos.
  17. Curtir
    BrunoWots deu reputação a Codex NG em In Game Account Manager TFS 1.3 / OTX3   
    Not completely tested and not all features are working but I am releasing this so that it is considered to be fixed and merged with the official branch.
     
    Sql
    INSERT INTO `players` (`id`, `name`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `skull`, `skulltime`, `lastlogout`, `blessings`, `onlinetime`, `deletion`, `balance`, `offlinetraining_time`, `offlinetraining_skill`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries`) VALUES (1, 'Account Manager', 1, 1, 1, 1, 150, 150, 0, 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, '', 40000, 1, 1535311649, 16777343, 1, 0, 0, 1535311709, 0, 2958, 0, 0, 43200, -1, 2520, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0);  
    INSERT INTO `accounts` (`id`, `name`, `password`, `secret`, `type`, `premdays`, `lastday`, `vippoints`, `email`, `creation`) VALUES (1, '1', '356a192b7913b04c54574d18c28d46e6395428ab', NULL, 1, 365, 1535263046, '', '', 0);  
    configmanager.cpp
    // account manager boolean[ACCOUNT_MANAGER] = getGlobalBoolean(L, "accountManager", true); integer[AM_LEVEL] = getGlobalNumber(L, "startLevel", 1); integer[AM_EXPERIENCE] = getGlobalNumber(L, "experience", 0); integer[AM_MAGLEVEL] = getGlobalNumber(L, "level", 0); integer[AM_FIST] = getGlobalNumber(L, "fist", 10); integer[AM_CLUB] = getGlobalNumber(L, "club", 10); integer[AM_SWORD] = getGlobalNumber(L, "sword", 10); integer[AM_AXE] = getGlobalNumber(L, "axe", 10); integer[AM_SHIELD] = getGlobalNumber(L, "shield", 10); integer[AM_DIST] = getGlobalNumber(L, "distance", 10); integer[AM_FISH] = getGlobalNumber(L, "fish", 10); integer[AM_SOUL] = getGlobalNumber(L, "soul", 100); integer[AM_BALANCE] = getGlobalNumber(L, "balance", 0); integer[AM_OFFLINE_TRAIN] = getGlobalNumber(L, "offlineTrainingTime", 0); integer[AM_STAMINA] = getGlobalNumber(L, "stamina", 0); integer[AM_LOOK_ADDONS] = getGlobalNumber(L, "lookAddons", 0); integer[AM_MOUNT_ID] = getGlobalNumber(L, "mountId", 0); integer[AM_TOWN_ID] = getGlobalNumber(L, "startTownId", 1); integer[AM_SPAWNPOS_X] = getGlobalNumber(L, "temple_x", 0); integer[AM_SPAWNPOS_Y] = getGlobalNumber(L, "temple_y", 0); integer[AM_SPAWNPOS_Z] = getGlobalNumber(L, "temple_z", 0); integer[AM_MAX_HP] = getGlobalNumber(L, "baseHP", 150); integer[AM_MAX_MP] = getGlobalNumber(L, "baseMP", 0); integer[AM_MAX_CAP] = getGlobalNumber(L, "baseCAP", 400); integer[AM_MALE] = getGlobalNumber(L, "maleOutfit", 128); integer[AM_FEMALE] = getGlobalNumber(L, "femaleOutfit", 136); boolean[AM_CHOOSEVOC] = getGlobalBoolean(L, "chooseVocation", false); boolean[AM_GENERATE_ACCOUNT_NUMBER] = getGlobalBoolean(L, "generateAccountNumber", false); // xml or lua boolean[USE_XML] = getGlobalBoolean(L, "useXml", false); configmanager.h
    booleans
    // account manager ACCOUNT_MANAGER, NAMELOCK_MANAGER, AM_CHOOSEVOC, AM_GENERATE_ACCOUNT_NUMBER, // -- // lua or xml USE_XML,  
    integers
    // account manager AM_LEVEL, AM_EXPERIENCE, AM_MAGLEVEL, AM_FIST, AM_CLUB, AM_SWORD, AM_AXE, AM_SHIELD, AM_DIST, AM_FISH, AM_SOUL, AM_BALANCE, AM_OFFLINE_TRAIN, AM_STAMINA, AM_LOOK_ADDONS, AM_MOUNT_ID, AM_TOWN_ID, AM_SPAWNPOS_X, AM_SPAWNPOS_Y, AM_SPAWNPOS_Z, AM_MAX_HP, AM_MAX_MP, AM_MAX_CAP, AM_MALE, AM_FEMALE, // --  
    creature.h
    // account manager virtual bool isAccountManager() const { return false; } // --  
    game.cpp
    find this inside of Game:playerSay
    uint32_t muteTime = player->isMuted(); if (muteTime > 0) { std::ostringstream ss; ss << "You are still muted for " << muteTime << " seconds."; player->sendTextMessage(MESSAGE_STATUS_SMALL, ss.str()); return; } and place this right underneath
    // account manager if(player->isAccountManager()) { player->removeMessageBuffer(); internalCreatureSay(player, TALKTYPE_SAY, text, false); return; } // --  
    find this in Game::internalCreatureSay
    if (text.empty()) { return false; } and place this above it
    // account manager Player* player = creature->getPlayer(); if(player && player->isAccountManager()) { player->manageAccount(text); return true; } // --  
    add this to house.cpp
    // account manager void House::updateDoorDescription(std::string _name/* = ""*/) { std::string tmp = "house"; /* no isGuild method (atm) if(isGuild()) tmp = "hall"; */ char houseDescription[200]; const int32_t housePrice = g_config.getNumber(ConfigManager::HOUSE_PRICE); if(owner) { /* if(isGuild()) IOGuild::getInstance()->getGuildById(_name, owner); */ if(_name.empty()) IOLoginData::getInstance()->getNameByGuid(owner, _name); sprintf(houseDescription, "It belongs to %s '%s'. %s owns this %s.", tmp.c_str(), houseName.c_str(), _name.c_str(), tmp.c_str()); } else sprintf(houseDescription, "It belongs to %s '%s'. Nobody owns this %s. It costs %lu gold coins.", tmp.c_str(), houseName.c_str(), tmp.c_str(), ( housePrice != -1 ? (houseTiles.size() * housePrice) : 0 ) ); for (const auto& it : doorSet) { it->setSpecialDescription(houseDescription); } } // --  
    house.h
    find this void updateDoorDescription() const; and place this right underneath it
    void updateDoorDescription(std::string _name = "");  
    iologindata.cpp
    find this #include "game.h" and add this below it
    // account manager #include "vocation.h" // --  
    find this extern Game g_game; and add this below it
    // account manager extern Vocation g_vocations; // --  
    inside of this IOLoginData::loginserverAuthentication find this
    result = db.storeQuery(query.str()); if (result) { do { if (result->getNumber<uint64_t>("deletion") == 0) { account.characters.push_back(result->getString("name")); } } while (result->next()); std::sort(account.characters.begin(), account.characters.end()); } return true; and replace it with this
    result = db.storeQuery(query.str()); // account manager if(!result){ // give the account the account manager to use if they have no account account.characters.push_back("Account Manager"); return true; } // -- if (result) { // allow them to access the account manager if there are players on the account if (account.id != 1){ account.characters.push_back("Account Manager"); } do { if (result->getNumber<uint64_t>("deletion") == 0) { account.characters.push_back(result->getString("name")); } } while (result->next()); std::sort(account.characters.begin(), account.characters.end()); } return true;  
    add this
    // account manager bool IOLoginData::getAccountId(const std::string& name, uint32_t& number) { if(!name.length()) return false; Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `id` FROM `accounts` WHERE `name` LIKE " << db.escapeString(name) << " LIMIT 1;"; DBResult_ptr result; if(!(result = db.storeQuery(query.str()))) return false; number = result->getNumber<uint32_t>("id"); return true; } // -- find this in IOLoginData::updateOnlineStatus
    if (g_config.getBoolean(ConfigManager::ALLOW_CLONES)) { return; } and add this
    // account manager if(g_config.getBoolean(ConfigManager::ACCOUNT_MANAGER)){ return; } // --  
    add this
    // account manager bool IOLoginData::getNameByGuid(uint32_t guid, std::string& name) { std::ostringstream query; query << "SELECT `name` FROM `players` WHERE `id` = " << guid << " AND `deleted` = 0 LIMIT 1;"; DBResult_ptr result = Database::getInstance().storeQuery(query.str()); if (!result) { return false; } name = result->getString("name"); nameCacheMap[guid] = name; return true; } // -- Now add all these
    // account manager bool IOLoginData::accountIdExists(uint32_t accountId) { Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `id` FROM `accounts` WHERE `id` = " << accountId << " LIMIT 1"; DBResult_ptr result = db.storeQuery(query.str()); if(!result) return false; return true; } bool IOLoginData::accountNameExists(const std::string& name) { Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `id` FROM `accounts` WHERE `name` LIKE " << db.escapeString(name) << " LIMIT 1"; DBResult_ptr result = db.storeQuery(query.str()); if(!result) return false; return true; } bool IOLoginData::getPassword(uint32_t accountId, std::string& password, std::string name/* = ""*/) { Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `password` FROM `accounts` WHERE `id` = " << accountId << " LIMIT 1"; DBResult_ptr result = db.storeQuery(query.str()); if(!result) return false; if(name.empty() || name == "Account Manager") { password = result->getString("password"); return true; } std::string tmpPassword = result->getString("password"); query.str(""); query << "SELECT `name` FROM `players` WHERE `account_id` = " << accountId; result = db.storeQuery(query.str()); if(!result) return false; do { if(result->getString("name") != name) continue; password = tmpPassword; return true; } while(result->next()); return false; } // accountId should be id because the server references the index and not the actual account data bool IOLoginData::setPassword(uint32_t accountId, std::string newPassword) { std::string ePassword = transformToSHA1(newPassword); Database& db = Database::getInstance(); std::ostringstream query; query << "UPDATE `accounts` SET `password` = " << db.escapeString(ePassword) << " WHERE `id` = " << accountId << ";"; return db.executeQuery(query.str()); } // not using recovery key atm but still good to have bool IOLoginData::validRecoveryKey(uint32_t accountId, std::string recoveryKey) { std::string nRecoveryKey = transformToSHA1(recoveryKey); Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `id` FROM `accounts` WHERE `id` = " << accountId << " AND `recoverykey` "; query << "LIKE " << db.escapeString(nRecoveryKey) << " LIMIT 1"; DBResult_ptr result = db.storeQuery(query.str()); if(!result) return false; return true; } bool IOLoginData::setRecoveryKey(uint32_t accountId, std::string newRecoveryKey) { std::string nRecoveryKey = transformToSHA1(newRecoveryKey); Database& db = Database::getInstance(); std::ostringstream query; std::cout << "account id " << accountId << std::endl; query << "UPDATE `accounts` SET `recoverykey` = " << db.escapeString(nRecoveryKey) << " WHERE `name` = " << accountId << ";"; return db.executeQuery(query.str()); } uint64_t IOLoginData::createAccount(std::string name, std::string password) { std::string ePassword = transformToSHA1(password); Database& db = Database::getInstance(); std::ostringstream query; query << "INSERT INTO `accounts` (`id`, `name`, `password`) VALUES (NULL, " << db.escapeString(name) << ", " << db.escapeString(ePassword) << ")"; if(!db.executeQuery(query.str())) return 0; return db.getLastInsertId(); } // not tested yet bool IOLoginData::changeName(uint32_t guid, std::string newName, std::string oldName) { Database& db = Database::getInstance(); std::ostringstream query; query << "INSERT INTO `player_namelocks` (`player_id`, `name`, `new_name`, `date`) VALUES ("<< guid << ", " << db.escapeString(oldName) << ", " << db.escapeString(newName) << ", " << time(NULL) << ")"; DBResult_ptr result = db.storeQuery(query.str()); if (!result) { return false; } query.str(""); query << "UPDATE `players` SET `name` = " << db.escapeString(newName) << " WHERE `id` = " << guid << " LIMIT 1"; result = db.storeQuery(query.str()); if (!result) { return false; } GuidCacheMap::iterator it = guidCacheMap.find(oldName); if(it != guidCacheMap.end()) { guidCacheMap.erase(it); guidCacheMap[newName] = guid; } nameCacheMap[guid] = newName; return true; } bool IOLoginData::createCharacter(uint32_t accountId, std::string characterName, uint32_t vocationId /*int32_t vocationId */, uint16_t sex) { if(playerExists(characterName)){ return false; } // a little bulky but whatever lol uint32_t healthMax = g_config.getNumber(ConfigManager::AM_MAX_HP); uint32_t manaMax = g_config.getNumber(ConfigManager::AM_MAX_MP); uint32_t capMax = g_config.getNumber(ConfigManager::AM_MAX_CAP); uint16_t lookType = (sex % 2) ? g_config.getNumber(ConfigManager::AM_MALE) : g_config.getNumber(ConfigManager::AM_FEMALE); uint16_t lookAddons = g_config.getNumber(ConfigManager::AM_LOOK_ADDONS); uint16_t magLevel = g_config.getNumber(ConfigManager::AM_MAGLEVEL); uint16_t townId = g_config.getNumber(ConfigManager::AM_TOWN_ID); uint16_t spawnX = g_config.getNumber(ConfigManager::AM_SPAWNPOS_X); uint16_t spawnY = g_config.getNumber(ConfigManager::AM_SPAWNPOS_Y); uint16_t spawnZ = g_config.getNumber(ConfigManager::AM_SPAWNPOS_Z); uint32_t level = g_config.getNumber(ConfigManager::AM_LEVEL); uint64_t exp = g_config.getNumber(ConfigManager::AM_EXPERIENCE); uint32_t fist = g_config.getNumber(ConfigManager::AM_FIST); uint32_t club = g_config.getNumber(ConfigManager::AM_CLUB); uint32_t sword = g_config.getNumber(ConfigManager::AM_SWORD); uint32_t axe = g_config.getNumber(ConfigManager::AM_AXE); uint32_t shield = g_config.getNumber(ConfigManager::AM_SHIELD); uint32_t dist = g_config.getNumber(ConfigManager::AM_DIST); uint32_t fish = g_config.getNumber(ConfigManager::AM_FISH); uint32_t soul = g_config.getNumber(ConfigManager::AM_SOUL); uint64_t balance = g_config.getNumber(ConfigManager::AM_BALANCE); int32_t offlineTrainingTime = g_config.getNumber(ConfigManager::AM_OFFLINE_TRAIN); uint16_t stamina = g_config.getNumber(ConfigManager::AM_STAMINA); if(level > 1){ exp += Player::getExpForLevel(level); healthMax *= level; manaMax *= level; capMax *= level; } Database& db = Database::getInstance(); std::string name = db.escapeString(characterName); std::ostringstream query, initialQuery, lastQuery, selectChar; // since character creation wants to use the account name when it setups up the player as the account id // we'll ask the database to get the id of the account since that is how the players are listed in the character list selectChar << "SELECT `id` FROM `accounts` WHERE `name` = " << accountId << ";"; DBResult_ptr result = db.storeQuery(selectChar.str()); if (!result){ return false; } accountId = result->getNumber<uint32_t>("id"); // this is to counteract the foreign key issue initialQuery << "SET FOREIGN_KEY_CHECKS=0;"; lastQuery << "SET FOREIGN_KEY_CHECKS=1;"; db.executeQuery(initialQuery.str()); query << "INSERT INTO `players` (`name`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `skull`, `skulltime`, `lastlogout`, `blessings`, `onlinetime`, `deletion`, `balance`, `offlinetraining_time`, `offlinetraining_skill`, `stamina`, `skill_fist`, `skill_fist_tries`, `skill_club`, `skill_club_tries`, `skill_sword`, `skill_sword_tries`, `skill_axe`, `skill_axe_tries`, `skill_dist`, `skill_dist_tries`, `skill_shielding`, `skill_shielding_tries`, `skill_fishing`, `skill_fishing_tries`) VALUES (" << name << ", 1, " << accountId << ", " << level << ", " << vocationId << ", " << healthMax << ", " << healthMax << ", " << exp << ", 0, 0, 0, 0, " << lookType << ", " << lookAddons << ", " << magLevel << ", " << manaMax << ", " << manaMax << ", 0, " << soul << ", " << townId << ", " << spawnX << ", " << spawnY << ", " << spawnZ << ", 0x0, " << capMax << ", " << sex << ", 0, 0, 1, 0, 0, 0, 0, 0, 0, " << balance << ", " << offlineTrainingTime << ", -1, " << stamina << ", " << fist << ", 0, " << club << ", 0, " << sword << ", 0, " << axe << ", 0, " << dist << ", 0, " << shield << ", 0, " << fish << ", 0);"; if(db.executeQuery(query.str())){ db.executeQuery(lastQuery.str()); return true; } db.executeQuery(lastQuery.str()); return false; } // not tested DeleteCharacter_t IOLoginData::deleteCharacter(uint32_t accountId, const std::string characterName) { if(g_game.getPlayerByName(characterName)) return DELETE_ONLINE; Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `id` FROM `players` WHERE `name` LIKE " << db.escapeString(characterName) << " AND `account_id` = " << accountId << " AND `deleted` = 0 LIMIT 1"; DBResult_ptr result = db.storeQuery(query.str()); if(!result) return DELETE_INTERNAL; uint32_t id = result->getNumber<uint32_t>("id"); House* house = g_game.map.houses.getHouseByPlayerId(id); if(house) return DELETE_HOUSE; /* if(IOGuild::getInstance()->getGuildLevel(id) == 3) return DELETE_LEADER; */ query.str(""); query << "UPDATE `players` SET `deleted` = 1 WHERE `id` = " << id << ";"; if(!db.executeQuery(query.str())) return DELETE_INTERNAL; query.str(""); query << "DELETE FROM `guild_invites` WHERE `player_id` = " << id; db.executeQuery(query.str()); query.str(""); query << "DELETE FROM `player_viplist` WHERE `vip_id` = " << id; db.executeQuery(query.str()); /* for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it) { VIPListSet::iterator it_ = it->second->VIPList.find(id); if(it_ != it->second->VIPList.end()) it->second->VIPList.erase(it_); } */ return DELETE_SUCCESS; } bool IOLoginData::playerExists(uint32_t guid, bool multiworld /*= false*/, bool checkCache /*= true*/) { if(checkCache) { NameCacheMap::iterator it = nameCacheMap.find(guid); if(it != nameCacheMap.end()) return true; } Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `name` FROM `players` WHERE `id` = " << guid << " AND `deleted` = 0"; query << " LIMIT 1"; DBResult_ptr result = db.storeQuery(query.str()); if(!result) return false; const std::string name = result->getString("name"); nameCacheMap[guid] = name; return true; } bool IOLoginData::playerExists(std::string& name, bool multiworld /*= false*/, bool checkCache /*= true*/) { if(checkCache) { GuidCacheMap::iterator it = guidCacheMap.find(name); if(it != guidCacheMap.end()) { name = it->first; return true; } } Database& db = Database::getInstance(); std::ostringstream query; query << "SELECT `id`, `name` FROM `players` WHERE `name` LIKE " << db.escapeString(name); /*<< " AND `deleted` = 0"; */ query << " LIMIT 1"; DBResult_ptr result = db.storeQuery(query.str()); if(!result) return false; name = result->getString("name"); guidCacheMap[name] = result->getNumber<int32_t>("id"); return true; } // --  
    iologindata.h
    find this #include "database.h" and place this right underneath
    // account manager enum DeleteCharacter_t { DELETE_INTERNAL, DELETE_LEADER, DELETE_HOUSE, DELETE_ONLINE, DELETE_SUCCESS }; // --  
    find this
    class IOLoginData { public: and add this under it
    // account manager virtual ~IOLoginData() {} static IOLoginData* getInstance() { static IOLoginData instance; return &instance; } // -- find this static AccountType_t getAccountType(uint32_t accountId); and place this right below it
    // account manager bool accountIdExists(uint32_t accountId); bool accountNameExists(const std::string& name); bool getAccountId(const std::string& name, uint32_t& number); bool getNameByGuid(uint32_t guid, std::string& name); bool playerExists(uint32_t guid, bool multiworld = false, bool checkCache = true); bool playerExists(std::string& name, bool multiworld = false, bool checkCache = true); bool changeName(uint32_t guid, std::string newName, std::string oldName); bool createCharacter(uint32_t accountId, std::string characterName, uint32_t vocationId /* int32_t vocationId */, uint16_t sex); DeleteCharacter_t deleteCharacter(uint32_t accountId, const std::string characterName); bool getPassword(uint32_t accountId, std::string& password, std::string name = ""); bool setPassword(uint32_t accountId, std::string newPassword); bool validRecoveryKey(uint32_t accountId, std::string recoveryKey); bool setRecoveryKey(uint32_t accountId, std::string newRecoveryKey); uint64_t createAccount(std::string name, std::string password); // -- find this static void removePremiumDays(uint32_t accountId, int32_t removeDays); and place this right below it
    // account manager protected: struct StringCompareCase { bool operator()(const std::string& l, const std::string& r) const { return strcasecmp(l.c_str(), r.c_str()) < 0; } }; typedef std::map<std::string, uint32_t, StringCompareCase> GuidCacheMap; GuidCacheMap guidCacheMap; typedef std::map<uint32_t, std::string> NameCacheMap; NameCacheMap nameCacheMap; // --  
    luascript.cpp
    find this registerEnum(ZONE_NORMAL) and place this underneath
    // account manager registerEnum(MANAGER_NONE) registerEnum(MANAGER_NEW) registerEnum(MANAGER_ACCOUNT) registerEnum(MANAGER_NAMELOCK) // --  
    find this registerMethod("Player", "getLastLogout", LuaScriptInterface::luaPlayerGetLastLogout);
    and place this right underneath
    // account manager registerMethod("Player", "getAccountManager", LuaScriptInterface::luaGetPlayerAccountManager); // --  
    find this
    int LuaScriptInterface::luaPlayerGetLastLogout(lua_State* L) { // player:getLastLogout() Player* player = getUserdata<Player>(L, 1); if (player) { lua_pushnumber(L, player->getLastLogout()); } else { lua_pushnil(L); } return 1; } and place this under it
    int32_t LuaScriptInterface::luaGetPlayerAccountManager(lua_State* L) { // player:getAccountManager() Player* player = getUserdata<Player>(L, 1); if (player) { lua_pushnumber(L, player->accountManager); } else { lua_pushnil(L); } return 1; } luascript.h
    find this static int luaPlayerGetLastLogout(lua_State* L); and place this under it
    // account manager static int luaGetPlayerAccountManager(lua_State* L); // -- map.cpp
    look for bool Map:placeCreature(const Position& centerPos, Creature* creature, bool extendedPos/* = false*/, bool forceLogin/* = false*/)
    look for this
    Tile* tile = getTile(centerPos.x, centerPos.y, centerPos.z); if (tile) { placeInPZ = tile->hasFlag(TILESTATE_PROTECTIONZONE); ReturnValue ret = tile->queryAdd(0, *creature, 1, FLAG_IGNOREBLOCKITEM); foundTile = forceLogin || ret == RETURNVALUE_NOERROR || ret == RETURNVALUE_PLAYERISNOTINVITED; } else { placeInPZ = false; foundTile = false; } and replace it with this
    Tile* tile = getTile(centerPos.x, centerPos.y, centerPos.z); if (tile) { placeInPZ = tile->hasFlag(TILESTATE_PROTECTIONZONE); // account manager uint32_t flags = FLAG_IGNOREBLOCKITEM; if(creature->isAccountManager()) flags |= FLAG_IGNOREBLOCKCREATURE; // -- ReturnValue ret = tile->queryAdd(0, *creature, 1, flags); foundTile = forceLogin || ret == RETURNVALUE_NOERROR || ret == RETURNVALUE_PLAYERISNOTINVITED; } else { placeInPZ = false; foundTile = false; }  
    player.cpp
    find this #include <bitset>
    and place this under it
    // account manager #include "ban.h" // --  
    look for this
    Player::Player(ProtocolGame_ptr p) : Creature(), lastPing(OTSYS_TIME()), lastPong(lastPing), inbox(new Inbox(ITEM_INBOX)), client(std::move(p)) { inbox->incrementReferenceCounter(); } and replace it with this
    Player::Player(ProtocolGame_ptr p) : Creature(), lastPing(OTSYS_TIME()), lastPong(lastPing), inbox(new Inbox(ITEM_INBOX)), client(std::move(p)) { // account manager for(int8_t i = 0; i <= states; i++) { talkState[i] = false; } accountManager = MANAGER_NONE; // -- inbox->incrementReferenceCounter(); }  
    add this
    // account manager void Player::manageAccount(const std::string &text) { std::stringstream msg; msg << "Account Manager: "; bool noSwap = true; switch(accountManager) { case MANAGER_NAMELOCK: { if(!talkState[1]) { managerString = text; trimString(managerString); if(managerString.length() < 4) msg << "Your name you want is too short, please select a longer name."; else if(managerString.length() > 20) msg << "The name you want is too long, please select a shorter name."; else if(!isValidName(managerString)) msg << "That name seems to contain invalid symbols, please choose another name."; else if(IOLoginData::getInstance()->playerExists(managerString, true)) msg << "A player with that name already exists, please choose another name."; else { std::string tmp = asLowerCaseString(managerString); if(tmp.substr(0, 4) != "god " && tmp.substr(0, 3) != "cm " && tmp.substr(0, 3) != "gm ") { talkState[1] = true; talkState[2] = true; msg << managerString << ", are you sure?"; } else msg << "Your character is not a staff member, please tell me another name!"; } } else if(checkText(text, "no") && talkState[2]) { talkState[1] = talkState[2] = false; msg << "What else would you like to name your character?"; } else if(checkText(text, "yes") && talkState[2]) { if(!IOLoginData::getInstance()->playerExists(managerString, true)) { uint32_t tmp = IOLoginData::getInstance()->getGuidByName(managerString2); if(tmp != 0 && IOLoginData::getInstance()->changeName(tmp, managerString, managerString2) && IOBan::isPlayerNamelocked(tmp)) { if(House* house = g_game.map.houses.getHouseByPlayerId(tmp)) house->updateDoorDescription(managerString); talkState[1] = true; talkState[2] = false; msg << "Your character has been successfully renamed, you should now be able to login at it without any problems."; } else { talkState[1] = talkState[2] = false; msg << "Failed to change your name, please try again."; } } else { talkState[1] = talkState[2] = false; msg << "A player with that name already exists, please choose another name."; } } else msg << "Sorry, but I can't understand you, please try to repeat that!"; break; } case MANAGER_ACCOUNT: { // pr(" manage account case ", managerNumber); Account account = IOLoginData::getInstance()->loadAccount(managerNumber); if(checkText(text, "cancel") || (checkText(text, "account") && !talkState[1])) { talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; msg << "Do you want to change your 'password', add a 'character', or 'delete' a character?"; } else if(checkText(text, "delete") && talkState[1]) { talkState[1] = false; talkState[2] = true; msg << "Which character would you like to delete?"; } else if(talkState[2]) { std::string tmp = text; trimString(tmp); if(!isValidName(tmp, false)) msg << "That name contains invalid characters, try to say your name again, you might have typed it wrong."; else { talkState[2] = false; talkState[3] = true; managerString = tmp; msg << "Do you really want to delete the character named " << managerString << "?"; } } else if(checkText(text, "yes") && talkState[3]) { switch(IOLoginData::getInstance()->deleteCharacter(managerNumber, managerString)) { case DELETE_INTERNAL: msg << "An error occured while deleting your character. Either the character does not belong to you or it doesn't exist."; break; case DELETE_SUCCESS: msg << "Your character has been deleted."; break; case DELETE_HOUSE: msg << "Your character owns a house. To make sure you really want to lose your house by deleting your character, you have to login and leave the house or pass it to someone else first."; break; case DELETE_LEADER: msg << "Your character is the leader of a guild. You need to disband or pass the leadership someone else to delete your character."; break; case DELETE_ONLINE: msg << "A character with that name is currently online, to delete a character it has to be offline."; break; } talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; } else if(checkText(text, "no") && talkState[3]) { talkState[1] = true; talkState[3] = false; msg << "Tell me what character you want to delete."; } else if(checkText(text, "password") && talkState[1]) { talkState[1] = false; talkState[4] = true; msg << "Tell me your new password please."; } else if(talkState[4]) { std::string tmp = text; trimString(tmp); if(tmp.length() < 6) msg << "That password is too short, at least 6 digits are required. Please select a longer password."; else if(!isValidPassword(tmp)) msg << "Your password contains invalid characters... please tell me another one."; else { talkState[4] = false; talkState[5] = true; managerString = tmp; msg << "Should '" << managerString << "' be your new password?"; } } else if(checkText(text, "yes") && talkState[5]) { talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; IOLoginData::getInstance()->setPassword(managerNumber, managerString); msg << "Your password has been changed."; } else if(checkText(text, "no") && talkState[5]) { talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; msg << "Then not."; } else if(checkText(text, "character") && talkState[1]) { if(account.characters.size() <= 15) { talkState[1] = false; talkState[6] = true; msg << "What would you like as your character name?"; } else { talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; msg << "Your account reach the limit of 15 players, you can 'delete' a character if you want to create a new one."; } } else if(talkState[6]) { managerString = text; trimString(managerString); if(managerString.length() < 4) msg << "Your name you want is too short, please select a longer name."; else if(managerString.length() > 20) msg << "The name you want is too long, please select a shorter name."; else if(!isValidName(managerString)) msg << "That name seems to contain invalid symbols, please choose another name."; else if(IOLoginData::getInstance()->playerExists(managerString, true)) msg << "A player with that name already exists, please choose another name."; else { std::string tmp = asLowerCaseString(managerString); if(tmp.substr(0, 4) != "god " && tmp.substr(0, 3) != "cm " && tmp.substr(0, 3) != "gm ") { talkState[6] = false; talkState[7] = true; msg << managerString << ", are you sure?"; } else msg << "Your character is not a staff member, please tell me another name!"; } } else if(checkText(text, "no") && talkState[7]) { talkState[6] = true; talkState[7] = false; msg << "What else would you like to name your character?"; } else if(checkText(text, "yes") && talkState[7]) { talkState[7] = false; talkState[8] = true; msg << "Should your character be a 'male' or a 'female'."; } else if(talkState[8] && (checkText(text, "female") || checkText(text, "male"))) { talkState[8] = false; talkState[9] = true; if(checkText(text, "female")) { msg << "A female, are you sure?"; managerSex = PLAYERSEX_FEMALE; } else { msg << "A male, are you sure?"; managerSex = PLAYERSEX_MALE; } } else if(checkText(text, "no") && talkState[9]) { talkState[8] = true; talkState[9] = false; msg << "Tell me... would you like to be a 'male' or a 'female'?"; } else if(checkText(text, "yes") && talkState[9]) { if(g_config.getBoolean(ConfigManager::AM_CHOOSEVOC)) { talkState[9] = false; talkState[11] = true; bool firstPart = true; g_vocations.getVocationMap(firstPart, msg); } else if(!IOLoginData::getInstance()->playerExists(managerString, true)) { talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; if(IOLoginData::getInstance()->createCharacter(managerNumber, managerString, managerNumber2, (uint16_t)managerSex)) msg << "Your character has been created."; else msg << "Your character couldn't be created, please try again."; } else { talkState[6] = true; talkState[9] = false; msg << "A player with that name already exists, please choose another name."; } } else if(talkState[11]) { g_vocations.getVocationConfirmation(text, talkState[11], talkState[12], managerNumber2, msg); if(msg.str().length() == 17) msg << "I don't understand what vocation you would like to be... could you please repeat it?"; } else if(checkText(text, "yes") && talkState[12]) { if(!IOLoginData::getInstance()->playerExists(managerString, true)) { talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; if(IOLoginData::getInstance()->createCharacter(managerNumber, managerString, managerNumber2, (uint16_t)managerSex)) msg << "Your character has been created."; else msg << "Your character couldn't be created, please try again."; } else { talkState[6] = true; talkState[9] = false; msg << "A player with that name already exists, please choose another name."; } } else if(checkText(text, "no") && talkState[12]) { talkState[11] = true; talkState[12] = false; msg << "No? Then what would you like to be?"; } else if(checkText(text, "recovery key") && talkState[1]) { talkState[1] = false; talkState[10] = true; msg << "Would you like a recovery key?"; } else if(checkText(text, "yes") && talkState[10]) { // std::cout << "recovery key " << account.recoveryKey << " empty? " << account.recoveryKey.empty() <<std::endl; /* if(!account.recoveryKey.empty()) msg << "Sorry, you already have a recovery key, for security reasons I may not give you a new one."; else { managerString = generateRecoveryKey(4, 4); IOLoginData::getInstance()->setRecoveryKey(managerNumber, managerString); msg << "Your recovery key is: " << managerString << "."; } */ talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; } else if(checkText(text, "no") && talkState[10]) { msg << "Then not."; talkState[1] = true; for(int8_t i = 2; i <= 12; i++) talkState[i] = false; } else msg << "Please read the latest message that I have specified, I don't understand the current requested action."; break; } case MANAGER_NEW: { if(checkText(text, "account") && !talkState[1]) { msg << "What would you like your password to be?"; talkState[1] = true; talkState[2] = true; } else if(talkState[2]) { std::string tmp = text; trimString(tmp); if(tmp.length() < 6) msg << "That password is too short, at least 6 digits are required. Please select a longer password."; else if(!isValidPassword(tmp)) msg << "Your password contains invalid characters... please tell me another one."; else { talkState[3] = true; talkState[2] = false; managerString = tmp; msg << managerString << " is it? 'yes' or 'no'?"; } } else if(checkText(text, "yes") && talkState[3]) { if(g_config.getBoolean(ConfigManager::AM_GENERATE_ACCOUNT_NUMBER)) { do sprintf(managerChar, "%d%d%d%d%d%d%d", random_range(2, 9), random_range(2, 9), random_range(2, 9), random_range(2, 9), random_range(2, 9), random_range(2, 9), random_range(2, 9)); while(IOLoginData::getInstance()->accountNameExists(managerChar)); uint32_t id = (uint32_t)IOLoginData::getInstance()->createAccount(managerChar, managerString); if(id) { accountManager = MANAGER_ACCOUNT; managerNumber = id; noSwap = talkState[1] = false; msg << "Your account has been created, you may manage it now, but remember your account name: '" << managerChar << "' and password: '" << managerString << "'! If the account name is too hard to remember, please note it somewhere."; } else msg << "Your account could not be created, please try again."; for(int8_t i = 2; i <= 5; i++) talkState[i] = false; } else { msg << "What would you like your account name to be?"; talkState[3] = false; talkState[4] = true; } } else if(checkText(text, "no") && talkState[3]) { talkState[2] = true; talkState[3] = false; msg << "What would you like your password to be then?"; } else if(talkState[4]) { std::string tmp = text; trimString(tmp); if(tmp.length() < 3) msg << "That account name is too short, at least 3 digits are required. Please select a longer account name."; else if(tmp.length() > 25) msg << "That account name is too long, not more than 25 digits are required. Please select a shorter account name."; else if(!isValidAccountName(tmp)) msg << "Your account name contains invalid characters, please choose another one."; else if(asLowerCaseString(tmp) == asLowerCaseString(managerString)) msg << "Your account name cannot be same as password, please choose another one."; else { sprintf(managerChar, "%s", tmp.c_str()); msg << managerChar << ", are you sure?"; talkState[4] = false; talkState[5] = true; } } else if(checkText(text, "yes") && talkState[5]) { if(!IOLoginData::getInstance()->accountNameExists(managerChar)) { uint32_t id = (uint32_t)IOLoginData::getInstance()->createAccount(managerChar, managerString); if(id) { accountManager = MANAGER_ACCOUNT; managerNumber = id; noSwap = talkState[1] = false; msg << "Your account has been created, you may manage it now, but remember your account name: '" << managerChar << "' and password: '" << managerString << "'!"; } else msg << "Your account could not be created, please try again."; for(int8_t i = 2; i <= 5; i++) talkState[i] = false; } else { msg << "An account with that name already exists, please try another account name."; talkState[4] = true; talkState[5] = false; } } else if(checkText(text, "no") && talkState[5]) { talkState[5] = false; talkState[4] = true; msg << "What else would you like as your account name?"; } else if(checkText(text, "recover") && !talkState[6]) { talkState[6] = true; talkState[7] = true; msg << "What was your account name?"; } else if(talkState[7]) { managerString = text; if(IOLoginData::getInstance()->getAccountId(managerString, (uint32_t&)managerNumber)) { talkState[7] = false; talkState[8] = true; msg << "What was your recovery key?"; } else { msg << "Sorry, but account with such name doesn't exists."; talkState[6] = talkState[7] = false; } } else if(talkState[8]) { managerString2 = text; if(IOLoginData::getInstance()->validRecoveryKey(managerNumber, managerString2) && managerString2 != "0") { sprintf(managerChar, "%s%d", g_config.getString(ConfigManager::SERVER_NAME).c_str(), random_range(100, 999)); IOLoginData::getInstance()->setPassword(managerNumber, managerChar); msg << "Correct! Your new password is: " << managerChar << "."; } else msg << "Sorry, but this key doesn't match to account you gave me."; talkState[7] = talkState[8] = false; } else msg << "Sorry, but I can't understand you, please try to repeat that."; break; } default: return; break; } sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, msg.str().c_str()); if(!noSwap) sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Hint: Type 'account' to manage your account and if you want to start over then type 'cancel'."); } // -- player.h
    find class Guild; and add this below it
    // account manager enum AccountManager_t { MANAGER_NONE, MANAGER_NEW, MANAGER_ACCOUNT, MANAGER_NAMELOCK }; // -- next find this void addList() override; and add this below
    // account manager void manageAccount(const std::string& text); bool isAccountManager() const {return (accountManager != MANAGER_NONE);} template <typename T> inline void pr(std::string s, T const& v) { std::cout << s << v << std::endl; }; // -- find this
    void disconnect() { if (client) { client->disconnect(); } } place this under it
    // account manager bool isVirtual() const { return (getID() == 0); } // -- find this int32_t idleTime = 0;
    and place this below it
    // account manager int32_t managerNumber; uint32_t managerNumber2; std::string managerString, managerString2; int8_t states = 13; bool talkState[13]; // -- find this OperatingSystem_t operatingSystem = CLIENTOS_NONE;
    and place this below it
    // account manager AccountManager_t accountManager = MANAGER_NONE; PlayerSex_t managerSex; char managerChar[100]; // -- protocolgame.cpp
    find this void ProtocolGame::login(const std::string& name, uint32_t accountId, OperatingSystem_t operatingSystem)
    find this
    void ProtocolGame::login(const std::string& name, uint32_t accountId, OperatingSystem_t operatingSystem) { //dispatcher thread Player* foundPlayer = g_game.getPlayerByName(name); if (!foundPlayer || g_config.getBoolean(ConfigManager::ALLOW_CLONES)) { player = new Player(getThis()); player->setName(name); player->incrementReferenceCounter(); player->setID(); if (!IOLoginData::preloadPlayer(player, name)) { disconnectClient("Your character could not be loaded."); return; } if (IOBan::isPlayerNamelocked(player->getGUID())) { disconnectClient("Your character has been namelocked."); return; } and replace it with this
    void ProtocolGame::login(const std::string& name, uint32_t accountId, OperatingSystem_t operatingSystem) { //dispatcher thread Player* foundPlayer = g_game.getPlayerByName(name); if(!foundPlayer || name == "Account Manager" || g_config.getBoolean(ConfigManager::ALLOW_CLONES) ) { player = new Player(getThis()); player->setName(name); player->incrementReferenceCounter(); player->setID(); if (!IOLoginData::preloadPlayer(player, name)) { disconnectClient("Your character could not be loaded."); return; } if (IOBan::isPlayerNamelocked(player->getGUID()) && accountId != 1) { if(g_config.getBoolean(ConfigManager::NAMELOCK_MANAGER)) { player->name = "Account Manager"; player->accountManager = MANAGER_NAMELOCK; player->managerNumber = accountId; player->managerString2 = name; } else { disconnectClient("Your character has been namelocked."); return; } }else if(player->getName() == "Account Manager" && g_config.getBoolean(ConfigManager::ACCOUNT_MANAGER)) { if(accountId != 1) { player->accountManager = MANAGER_ACCOUNT; player->managerNumber = accountId; } else { player->accountManager = MANAGER_NEW; } } in that same method underneath this
    if (g_game.getGameState() == GAME_STATE_CLOSING && !player->hasFlag(PlayerFlag_CanAlwaysLogin)) { disconnectClient("The game is just going down.\nPlease try again later."); return; } if (g_game.getGameState() == GAME_STATE_CLOSED && !player->hasFlag(PlayerFlag_CanAlwaysLogin)) { disconnectClient("Server is currently closed.\nPlease try again later."); return; } place this
    // account manager if (g_config.getBoolean(ConfigManager::ONE_PLAYER_ON_ACCOUNT) && !player->isAccountManager() && player->getAccountType() < ACCOUNT_TYPE_GAMEMASTER && g_game.getPlayerByAccount(player->getAccount())) { bool found = false; std::vector<Player*> tmp; tmp.push_back(g_game.getPlayerByAccount(accountId)); for(std::vector<Player*>::iterator it = tmp.begin(); it != tmp.end(); ++it) { if((*it)->getName() != name) continue; found = true; break; } if(tmp.size() > 0 && !found) { disconnectClient("You may only login with one character\nof your account at the same time."); return; } } // -- find this void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg)
    inside of there you are going to look for this
    std::string& token = sessionArgs[2]; uint32_t tokenTime = 0; try { tokenTime = std::stoul(sessionArgs[3]); } catch (const std::invalid_argument&) { disconnectClient("Malformed token packet."); return; } catch (const std::out_of_range&) { disconnectClient("Token time is too long."); return; } if (accountName.empty()) { disconnectClient("You must enter your account name."); return; } replace it with this
    // account manager if (accountName.empty()) { accountName = "1"; } if (password.empty()) { password = "1"; } // -- within that same method you will look for this
    uint32_t accountId = IOLoginData::gameworldAuthentication(accountName, password, characterName, token, tokenTime); if (accountId == 0) { disconnectClient("Account name or password is not correct."); return; } g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::login, getThis(), characterName, accountId, operatingSystem))); } and replace it with this
    uint32_t accountId = atoi(accountName.c_str()); g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::login, getThis(), characterName, accountId, operatingSystem))); }  
    this whole method you are going to replace void ProtocolGame::parsePacket(NetworkMessage& msg)
    void ProtocolGame::parsePacket(NetworkMessage& msg) { if (!acceptPackets || g_game.getGameState() == GAME_STATE_SHUTDOWN || msg.getLength() <= 0) { return; } uint8_t recvbyte = msg.getByte(); if (!player) { if (recvbyte == 0x0F) { disconnect(); } return; } //a dead player can not performs actions if (player->isRemoved() || player->getHealth() <= 0) { if (recvbyte == 0x0F) { disconnect(); return; } if (recvbyte != 0x14) { return; } } // account manager if(player->isAccountManager()) { switch(recvbyte) { case 0x14: g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::logout, getThis(), true, false))); break; break; case 0x96: parseSay(msg); break; default: sendCancelWalk(); break; } } else { // -- switch (recvbyte) { case 0x14: g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::logout, getThis(), true, false))); break; case 0x1D: addGameTask(&Game::playerReceivePingBack, player->getID()); break; case 0x1E: addGameTask(&Game::playerReceivePing, player->getID()); break; case 0x32: parseExtendedOpcode(msg); break; //otclient extended opcode case 0x64: parseAutoWalk(msg); break; case 0x65: addGameTask(&Game::playerMove, player->getID(), DIRECTION_NORTH); break; case 0x66: addGameTask(&Game::playerMove, player->getID(), DIRECTION_EAST); break; case 0x67: addGameTask(&Game::playerMove, player->getID(), DIRECTION_SOUTH); break; case 0x68: addGameTask(&Game::playerMove, player->getID(), DIRECTION_WEST); break; case 0x69: addGameTask(&Game::playerStopAutoWalk, player->getID()); break; case 0x6A: addGameTask(&Game::playerMove, player->getID(), DIRECTION_NORTHEAST); break; case 0x6B: addGameTask(&Game::playerMove, player->getID(), DIRECTION_SOUTHEAST); break; case 0x6C: addGameTask(&Game::playerMove, player->getID(), DIRECTION_SOUTHWEST); break; case 0x6D: addGameTask(&Game::playerMove, player->getID(), DIRECTION_NORTHWEST); break; case 0x6F: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), DIRECTION_NORTH); break; case 0x70: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), DIRECTION_EAST); break; case 0x71: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), DIRECTION_SOUTH); break; case 0x72: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), DIRECTION_WEST); break; case 0x77: parseEquipObject(msg); break; case 0x78: parseThrow(msg); break; case 0x79: parseLookInShop(msg); break; case 0x7A: parsePlayerPurchase(msg); break; case 0x7B: parsePlayerSale(msg); break; case 0x7C: addGameTask(&Game::playerCloseShop, player->getID()); break; case 0x7D: parseRequestTrade(msg); break; case 0x7E: parseLookInTrade(msg); break; case 0x7F: addGameTask(&Game::playerAcceptTrade, player->getID()); break; case 0x80: addGameTask(&Game::playerCloseTrade, player->getID()); break; case 0x82: parseUseItem(msg); break; case 0x83: parseUseItemEx(msg); break; case 0x84: parseUseWithCreature(msg); break; case 0x85: parseRotateItem(msg); break; case 0x87: parseCloseContainer(msg); break; case 0x88: parseUpArrowContainer(msg); break; case 0x89: parseTextWindow(msg); break; case 0x8A: parseHouseWindow(msg); break; case 0x8C: parseLookAt(msg); break; case 0x8D: parseLookInBattleList(msg); break; case 0x8E: /* join aggression */ break; case 0x96: parseSay(msg); break; case 0x97: addGameTask(&Game::playerRequestChannels, player->getID()); break; case 0x98: parseOpenChannel(msg); break; case 0x99: parseCloseChannel(msg); break; case 0x9A: parseOpenPrivateChannel(msg); break; case 0x9E: addGameTask(&Game::playerCloseNpcChannel, player->getID()); break; case 0xA0: parseFightModes(msg); break; case 0xA1: parseAttack(msg); break; case 0xA2: parseFollow(msg); break; case 0xA3: parseInviteToParty(msg); break; case 0xA4: parseJoinParty(msg); break; case 0xA5: parseRevokePartyInvite(msg); break; case 0xA6: parsePassPartyLeadership(msg); break; case 0xA7: addGameTask(&Game::playerLeaveParty, player->getID()); break; case 0xA8: parseEnableSharedPartyExperience(msg); break; case 0xAA: addGameTask(&Game::playerCreatePrivateChannel, player->getID()); break; case 0xAB: parseChannelInvite(msg); break; case 0xAC: parseChannelExclude(msg); break; case 0xBE: addGameTask(&Game::playerCancelAttackAndFollow, player->getID()); break; case 0xC9: /* update tile */ break; case 0xCA: parseUpdateContainer(msg); break; case 0xCB: parseBrowseField(msg); break; case 0xCC: parseSeekInContainer(msg); break; case 0xD2: addGameTask(&Game::playerRequestOutfit, player->getID()); break; case 0xD3: parseSetOutfit(msg); break; case 0xD4: parseToggleMount(msg); break; case 0xDC: parseAddVip(msg); break; case 0xDD: parseRemoveVip(msg); break; case 0xDE: parseEditVip(msg); break; case 0xE6: parseBugReport(msg); break; case 0xE7: /* thank you */ break; case 0xE8: parseDebugAssert(msg); break; case 0xF0: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerShowQuestLog, player->getID()); break; case 0xF1: parseQuestLine(msg); break; case 0xF2: parseRuleViolationReport(msg); break; case 0xF3: /* get object info */ break; case 0xF4: parseMarketLeave(); break; case 0xF5: parseMarketBrowse(msg); break; case 0xF6: parseMarketCreateOffer(msg); break; case 0xF7: parseMarketCancelOffer(msg); break; case 0xF8: parseMarketAcceptOffer(msg); break; case 0xF9: parseModalWindowAnswer(msg); break; default: // std::cout << "Player: " << player->getName() << " sent an unknown packet header: 0x" << std::hex << static_cast<uint16_t>(recvbyte) << std::dec << "!" << std::endl; break; } } // end of else if (msg.isOverrun()) { disconnect(); } } protocollogin.cpp
    within this method void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg)
    find this
    std::string accountName = msg.getString(); if (accountName.empty()) { disconnectClient("Invalid account name.", version); return; } std::string password = msg.getString(); if (password.empty()) { disconnectClient("Invalid password.", version); return; } replace it with this
    std::string accountName = msg.getString(); if (accountName.empty()) { // account manager if(!g_config.getBoolean(ConfigManager::ACCOUNT_MANAGER)){ disconnectClient("Invalid account name.", version); return; } accountName = "1"; } std::string password = msg.getString(); if (password.empty()) { // account manager if(!g_config.getBoolean(ConfigManager::ACCOUNT_MANAGER)){ disconnectClient("Invalid password.", version); return; } password = "1"; // sha1 "356a192b7913b04c54574d18c28d46e6395428ab" } tools.cpp add this to the bottom of the file
    // account manager int32_t round(float v) { int32_t t = (int32_t)std::floor(v); if((v - t) > 0.5) return t + 1; return t; } uint32_t rand24b() { return ((rand() << 12) ^ (rand())) & (0xFFFFFF); } float box_muller(float m, float s) { // normal random variate generator // mean m, standard deviation s float x1, x2, w, y1; static float y2; static bool useLast = false; if(useLast) // use value from previous call { y1 = y2; useLast = false; return (m + y1 * s); } do { double r1 = (((float)(rand()) / RAND_MAX)); double r2 = (((float)(rand()) / RAND_MAX)); x1 = 2.0 * r1 - 1.0; x2 = 2.0 * r2 - 1.0; w = x1 * x1 + x2 * x2; } while(w >= 1.0); w = sqrt((-2.0 * log(w)) / w); y1 = x1 * w; y2 = x2 * w; useLast = true; return (m + y1 * s); } int32_t random_range(int32_t lowestNumber, int32_t highestNumber, DistributionType_t type /*= DISTRO_UNIFORM*/) { if(highestNumber == lowestNumber) return lowestNumber; if(lowestNumber > highestNumber) std::swap(lowestNumber, highestNumber); switch(type) { case DISTRO_UNIFORM: return (lowestNumber + ((int32_t)rand24b() % (highestNumber - lowestNumber + 1))); case DISTRO_NORMAL: return (lowestNumber + int32_t(float(highestNumber - lowestNumber) * (float)std::min((float)1, std::max((float)0, box_muller(0.5, 0.25))))); default: break; } const float randMax = 16777216; return (lowestNumber + int32_t(float(highestNumber - lowestNumber) * float(1.f - sqrt((1.f * rand24b()) / randMax)))); } bool isLowercaseLetter(char character) { return (character >= 97 && character <= 122); } bool isUppercaseLetter(char character) { return (character >= 65 && character <= 90); } bool isNumber(char character) { return (character >= 48 && character <= 57); } bool isNumbers(std::string text) { uint32_t textLength = text.length(); for(uint32_t size = 0; size < textLength; size++) { if(!isNumber(text[size])) return false; } return true; } bool checkText(std::string text, std::string str) { trimString(text); return asLowerCaseString(text) == str; } std::string generateRecoveryKey(int32_t fieldCount, int32_t fieldLenght) { std::stringstream key; int32_t i = 0, j = 0, lastNumber = 99, number = 0; char character = 0, lastCharacter = 0; bool madeNumber = false, madeCharacter = false; do { do { madeNumber = madeCharacter = false; if((bool)random_range(0, 1)) { number = random_range(2, 9); if(number != lastNumber) { key << number; lastNumber = number; madeNumber = true; } } else { character = (char)random_range(65, 90); if(character != lastCharacter) { key << character; lastCharacter = character; madeCharacter = true; } } } while((!madeCharacter && !madeNumber) ? true : (++j && j < fieldLenght)); lastCharacter = character = number = j = 0; lastNumber = 99; if(i < fieldCount - 1) key << "-"; } while(++i && i < fieldCount); return key.str(); } bool isValidAccountName(std::string text) { toLowerCaseString(text); uint32_t textLength = text.length(); for(uint32_t size = 0; size < textLength; size++) { if(!isLowercaseLetter(text[size]) && !isNumber(text[size])) return false; } return true; } bool isValidPassword(std::string text) { toLowerCaseString(text); uint32_t textLength = text.length(); for(uint32_t size = 0; size < textLength; size++) { if(!isLowercaseLetter(text[size]) && !isNumber(text[size]) && !isPasswordCharacter(text[size])) return false; } return true; } bool isPasswordCharacter(char character) { return ((character >= 33 && character <= 47) || (character >= 58 && character <= 64) || (character >= 91 && character <= 96) || (character >= 123 && character <= 126)); } bool isValidName(std::string text, bool forceUppercaseOnFirstLetter/* = true*/) { uint32_t textLength = text.length(), lenBeforeSpace = 1, lenBeforeQuote = 1, lenBeforeDash = 1, repeatedCharacter = 0; char lastChar = 32; if(forceUppercaseOnFirstLetter) { if(!isUppercaseLetter(text[0])) return false; } else if(!isLowercaseLetter(text[0]) && !isUppercaseLetter(text[0])) return false; for(uint32_t size = 1; size < textLength; size++) { if(text[size] != 32) { lenBeforeSpace++; if(text[size] != 39) lenBeforeQuote++; else { if(lenBeforeQuote <= 1 || size == textLength - 1 || text[size + 1] == 32) return false; lenBeforeQuote = 0; } if(text[size] != 45) lenBeforeDash++; else { if(lenBeforeDash <= 1 || size == textLength - 1 || text[size + 1] == 32) return false; lenBeforeDash = 0; } if(text[size] == lastChar) { repeatedCharacter++; if(repeatedCharacter > 2) return false; } else repeatedCharacter = 0; lastChar = text[size]; } else { if(lenBeforeSpace <= 1 || size == textLength - 1 || text[size + 1] == 32) return false; lenBeforeSpace = lenBeforeQuote = lenBeforeDash = 0; } if(!(isLowercaseLetter(text[size]) || text[size] == 32 || text[size] == 39 || text[size] == 45 || (isUppercaseLetter(text[size]) && text[size - 1] == 32))) return false; } return true; } // -- tools.h
    find this #include "enums.h"
    and place this under it
    // account manager enum DistributionType_t { DISTRO_UNIFORM, DISTRO_SQUARE, DISTRO_NORMAL }; enum FileType_t { FILE_TYPE_XML, FILE_TYPE_LOG, FILE_TYPE_OTHER, FILE_TYPE_CONFIG, FILE_TYPE_MOD }; // -- find this
    std::string ucfirst(std::string str); std::string ucwords(std::string str); bool booleanString(const std::string& str); place this under it
    // account manager bool isValidAccountName(std::string text); bool isValidPassword(std::string text); bool isValidName(std::string text, bool forceUppercaseOnFirstLetter = true); bool isNumber(char character); bool isNumbers(std::string text); bool isPasswordCharacter(char character); bool checkText(std::string text, std::string str); std::string generateRecoveryKey(int32_t fieldCount, int32_t fieldLength); int32_t random_range(int32_t lowest_number, int32_t highest_number, DistributionType_t type = DISTRO_UNIFORM); int32_t round(float v); uint32_t rand24b(); float box_muller(float m, float s); // -- vocation.cpp
    // account manager void Vocations::getVocationMap(bool &firstPart, std::stringstream &msg) { for(auto it = vocationsMap.begin(); it != vocationsMap.end(); ++it) { bool isXml = g_config.getBoolean(ConfigManager::USE_XML); if(it->first == ((isXml) ? it->second.getFromVocation() : it->second.getId()) && it->first != 0) { if(firstPart) { msg << "What do you want to be... " << ((isXml) ? it->second.getVocDescription() : it->second.getVocName()); firstPart = false; } else if(it->first - 1 != 0){ msg << ", " << ((isXml) ? it->second.getVocDescription() : it->second.getVocName()); } else{ msg << " or " << ((isXml) ? it->second.getVocDescription() : it->second.getVocName()) << "."; } } } } // needs to set the proper vocation id void Vocations::getVocationConfirmation(std::string text, bool &talkState1, bool &talkState2, uint32_t &number /* int32_t &number */, std::stringstream &msg) { for(auto it = vocationsMap.begin(); it != vocationsMap.end(); ++it) { bool isXml = g_config.getBoolean(ConfigManager::USE_XML); std::string tmp = asLowerCaseString(it->second.getVocName()); if(checkText(text, tmp) && it != vocationsMap.end() && it->first == ((isXml) ? it->second.getFromVocation() : it->second.getId()) && it->first != 0) { msg << "So you would like to be " << ((isXml) ? it->second.getVocDescription() : it->second.getVocName()) << "... are you sure?"; number = it->first; talkState1 = false; talkState2 = true; } } } vocation.h
    find uint16_t getPromotedVocation(uint16_t vocationId) const;
    and place this underneath
    // account manager void getVocationMap(bool &firstPart, std::stringstream &msg); void getVocationConfirmation(std::string, bool&, bool&, uint32_t& /* int32_t& */, std::stringstream&); // --  
    modify your login.lua
    function onLogin(player) local accountManager = player:getAccountManager() if(accountManager == MANAGER_NONE) then local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!" if player:getLastLoginSaved() <= 0 then loginStr = loginStr .. " Please choose your outfit." player:sendOutfitWindow() else if loginStr ~= "" then player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr) end loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved())) end player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr) elseif(accountManager == MANAGER_NAMELOCK) then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Hello, it appears that your character has been namelocked, what would you like as your new name?") elseif(accountManager == MANAGER_ACCOUNT) then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Hello, type 'account' to manage your account and if you want to start over then type 'cancel'.") elseif(accountManager == MANAGER_NEW) then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Hello, type 'account' to create an account or type 'recover' to recover an account.") end  
    and finally add this to your config.lua
    -- Account Manager accountManager = true -- how many points do you want to give each account -- this applies only when they create the account vipPoints = 0 -- the default stats to start with experience = 0 -- uint64_t level = 1 soul = 100 -- uint8_t magic = 0 fist = 10 club = 10 sword = 10 axe = 10 shield = 10 distance = 10 fish = 10 -- incase you want to give the player a little starter money in their bank :) balance = 0 -- uint64_t offlineTrainingTime = 43200 -- int32_t stamina = 2520 -- uint16_t startTownId = 1 -- uint32_t temple_x = 0 temple_y = 0 temple_z = 0 baseHP = 150 baseMP = 0 baseCAP = 400 maleOutfit = 128 femaleOutfit = 136 -- give the player addons for their corresponding outfit if any lookAddons = 0 -- start the player off with a mount mountId = 0 chooseVocation = true generateAccountNumber = false useXML = true Here is a video demonstration of it working in OTX3 8.6, I have not made a video for it in TFS 1.3 because I added somethings to after making this video
     
  18. Curtir
    Para de ser mentiroso, o servidor é proprio meu, eu comecei do zero e utilizei scripts mistas open da internet e muitas do Printer, trabalhei nele por mais de 2 anos sozinho, algumas scripts foram feitas ou adaptadas por mim, quanto a source da distro foram contribuições do celohere e não do nekiro.
     
    Vlw irmão, você pode baixar as sources do celohere, são as mais compativeis com o servidor, é só da uma pesquisada no google [8.0] - TFS 1.2 que você acha facil, quando eu for atualizar aqui eu coloco as sources. tmj!
     
    Pessoal, quanto a alguns bug que passaram despercebidos eu vou atualizar, pois não teve quase ninguem no teste server e eu trabahei sozinho no servidor, só aguardarem, vlw.
  19. Gostei
    Olá comunidade, venho aqui hoje trazer um autêntico servidor de mapa real full 8.0 completo. Talvez esse seja um dos servidores mais raro e pedido postado de graça em qualquer comunidade tendo em vista que esse servidor pode ser avaliado em no mínimo 200$ Dólares. Sem contar que é um dos servidores mais querido da comunidade tibiana como por exemplo o kasteria e realera.
     
     
          -Servidor compatível com cliente 8.0 cipsoft original sem customização.
          Características:
    Quests 100% Mapa 100% Missões 100% Creaturas 100% NPC'S 100% Houses 100% Raids 100%  
    Quests do servidor:
     
     
     
          Características detalhadas:
          » Todas as quests/missões/tasks/questlong/acessos 8.0.
          » Todas as ilhas: Port Hope, Liberty Bay, Rookgaard e Svargrond.
          » Vocações balanceadas, danos de feitiços de 8.0/7.6 foram levemente ajustados para melhor.
          » Raid System: Todas as invasões que existiam antigamente estão aqui.
          » Todos os monstros balanceados.
          » Addons podem ser obtidos como tíbia real. Ao fazer missões e coletar os itens! Outras características!
          » As criaturas boss do Sistema do Raid executarão uma incursão em uma cidade ou vila próxima.
          » Quest da Spike Sword adicionada em Rookgaard!
     
          Recursos opcionais:
          » Teleport Trainer Dummy igual ao Kasteria.
          » Npc Casino no depósito de Thais.
          » Npc's Dijinn's em Thais.
          » Runas à venda em npc's
          » Raid player summon um poderoso mago "Lord'Paulistinha". xD
     
     
    Download:
    Scan: Link
     
          Imagens:
    .
    global_8.0.rar
  20. Obrigado
    Olá comunidade, venho aqui hoje trazer um autêntico servidor de mapa real full 8.0 completo. Talvez esse seja um dos servidores mais raro e pedido postado de graça em qualquer comunidade tendo em vista que esse servidor pode ser avaliado em no mínimo 200$ Dólares. Sem contar que é um dos servidores mais querido da comunidade tibiana como por exemplo o kasteria e realera.
     
     
          -Servidor compatível com cliente 8.0 cipsoft original sem customização.
          Características:
    Quests 100% Mapa 100% Missões 100% Creaturas 100% NPC'S 100% Houses 100% Raids 100%  
    Quests do servidor:
     
     
     
          Características detalhadas:
          » Todas as quests/missões/tasks/questlong/acessos 8.0.
          » Todas as ilhas: Port Hope, Liberty Bay, Rookgaard e Svargrond.
          » Vocações balanceadas, danos de feitiços de 8.0/7.6 foram levemente ajustados para melhor.
          » Raid System: Todas as invasões que existiam antigamente estão aqui.
          » Todos os monstros balanceados.
          » Addons podem ser obtidos como tíbia real. Ao fazer missões e coletar os itens! Outras características!
          » As criaturas boss do Sistema do Raid executarão uma incursão em uma cidade ou vila próxima.
          » Quest da Spike Sword adicionada em Rookgaard!
     
          Recursos opcionais:
          » Teleport Trainer Dummy igual ao Kasteria.
          » Npc Casino no depósito de Thais.
          » Npc's Dijinn's em Thais.
          » Runas à venda em npc's
          » Raid player summon um poderoso mago "Lord'Paulistinha". xD
     
     
    Download:
    Scan: Link
     
          Imagens:
    .
    global_8.0.rar
  21. Gostei
    Olá comunidade, venho aqui hoje trazer um autêntico servidor de mapa real full 8.0 completo. Talvez esse seja um dos servidores mais raro e pedido postado de graça em qualquer comunidade tendo em vista que esse servidor pode ser avaliado em no mínimo 200$ Dólares. Sem contar que é um dos servidores mais querido da comunidade tibiana como por exemplo o kasteria e realera.
     
     
          -Servidor compatível com cliente 8.0 cipsoft original sem customização.
          Características:
    Quests 100% Mapa 100% Missões 100% Creaturas 100% NPC'S 100% Houses 100% Raids 100%  
    Quests do servidor:
     
     
     
          Características detalhadas:
          » Todas as quests/missões/tasks/questlong/acessos 8.0.
          » Todas as ilhas: Port Hope, Liberty Bay, Rookgaard e Svargrond.
          » Vocações balanceadas, danos de feitiços de 8.0/7.6 foram levemente ajustados para melhor.
          » Raid System: Todas as invasões que existiam antigamente estão aqui.
          » Todos os monstros balanceados.
          » Addons podem ser obtidos como tíbia real. Ao fazer missões e coletar os itens! Outras características!
          » As criaturas boss do Sistema do Raid executarão uma incursão em uma cidade ou vila próxima.
          » Quest da Spike Sword adicionada em Rookgaard!
     
          Recursos opcionais:
          » Teleport Trainer Dummy igual ao Kasteria.
          » Npc Casino no depósito de Thais.
          » Npc's Dijinn's em Thais.
          » Runas à venda em npc's
          » Raid player summon um poderoso mago "Lord'Paulistinha". xD
     
     
    Download:
    Scan: Link
     
          Imagens:
    .
    global_8.0.rar
  22. Curtir
    BrunoWots deu reputação a oclipper em [SOURCE] BOT OTClient (Free - COM CAVEBOT)   
    BOT simples e atualizável para OTClient:

    PS.: Para Atualizar os Address basta ver meus tutoriais aqui no Forum.

    - Healing
    - Mana train
    - Full Light
    - Speed Hack
    - Alarm HP (pisca e som)
    - PK/player on screen Alarm
    - GM Alarm
    - Sio Friend
    - Auto Hur
    - Auto Mana Shield
    - CAVEBOT



    Address Panel, so you can easly update to your otserver


    Download Link: https://www.4shared.com/s/fQyNP1KKuea
    SCAN: https://www.virustotal.com/gui/file/3bd8d616aa9ba29d24283071998a962f6f2cd505d12bc2e7353c87362ddad19b?nocache=1
  23. Obrigado
    Olá comunidade, venho aqui hoje trazer um autêntico servidor de mapa real full 8.0 completo. Talvez esse seja um dos servidores mais raro e pedido postado de graça em qualquer comunidade tendo em vista que esse servidor pode ser avaliado em no mínimo 200$ Dólares. Sem contar que é um dos servidores mais querido da comunidade tibiana como por exemplo o kasteria e realera.
     
     
          -Servidor compatível com cliente 8.0 cipsoft original sem customização.
          Características:
    Quests 100% Mapa 100% Missões 100% Creaturas 100% NPC'S 100% Houses 100% Raids 100%  
    Quests do servidor:
     
     
     
          Características detalhadas:
          » Todas as quests/missões/tasks/questlong/acessos 8.0.
          » Todas as ilhas: Port Hope, Liberty Bay, Rookgaard e Svargrond.
          » Vocações balanceadas, danos de feitiços de 8.0/7.6 foram levemente ajustados para melhor.
          » Raid System: Todas as invasões que existiam antigamente estão aqui.
          » Todos os monstros balanceados.
          » Addons podem ser obtidos como tíbia real. Ao fazer missões e coletar os itens! Outras características!
          » As criaturas boss do Sistema do Raid executarão uma incursão em uma cidade ou vila próxima.
          » Quest da Spike Sword adicionada em Rookgaard!
     
          Recursos opcionais:
          » Teleport Trainer Dummy igual ao Kasteria.
          » Npc Casino no depósito de Thais.
          » Npc's Dijinn's em Thais.
          » Runas à venda em npc's
          » Raid player summon um poderoso mago "Lord'Paulistinha". xD
     
     
    Download:
    Scan: Link
     
          Imagens:
    .
    global_8.0.rar
  24. Obrigado
    Olá comunidade, venho aqui hoje trazer um autêntico servidor de mapa real full 8.0 completo. Talvez esse seja um dos servidores mais raro e pedido postado de graça em qualquer comunidade tendo em vista que esse servidor pode ser avaliado em no mínimo 200$ Dólares. Sem contar que é um dos servidores mais querido da comunidade tibiana como por exemplo o kasteria e realera.
     
     
          -Servidor compatível com cliente 8.0 cipsoft original sem customização.
          Características:
    Quests 100% Mapa 100% Missões 100% Creaturas 100% NPC'S 100% Houses 100% Raids 100%  
    Quests do servidor:
     
     
     
          Características detalhadas:
          » Todas as quests/missões/tasks/questlong/acessos 8.0.
          » Todas as ilhas: Port Hope, Liberty Bay, Rookgaard e Svargrond.
          » Vocações balanceadas, danos de feitiços de 8.0/7.6 foram levemente ajustados para melhor.
          » Raid System: Todas as invasões que existiam antigamente estão aqui.
          » Todos os monstros balanceados.
          » Addons podem ser obtidos como tíbia real. Ao fazer missões e coletar os itens! Outras características!
          » As criaturas boss do Sistema do Raid executarão uma incursão em uma cidade ou vila próxima.
          » Quest da Spike Sword adicionada em Rookgaard!
     
          Recursos opcionais:
          » Teleport Trainer Dummy igual ao Kasteria.
          » Npc Casino no depósito de Thais.
          » Npc's Dijinn's em Thais.
          » Runas à venda em npc's
          » Raid player summon um poderoso mago "Lord'Paulistinha". xD
     
     
    Download:
    Scan: Link
     
          Imagens:
    .
    global_8.0.rar
  25. Obrigado
    Muito bom, únicos problemas que encontrei são as casas que a maioria não estão corretas ou seja o housetile tem que cobrir apenas as paredes norte e oeste de cada casa e não a parede sul e leste,tirando isso e alguns monstros dentro de paredes e escadas e também as partes dos portais de acesso em forbidden islands ,esta tudo muito bom.Muito bom trabalho e obrigado por disponibilizar.(Não estou cobrando que você resolva tudo, apenas apontando para as pessoas que vão baixar corrigirem).

Informação Importante

Confirmação de Termo