Code Coupons + Worldmap update + Mini-games + Player Interaction wrap
Fixed several cases on the Cash Shop that would freeze some player actions when triggered, requiring exit Cash Shop to unstuck. Implemented Code Coupons, supporting several items bundled on the same code, and also devised a way to automate code generation. Added a current status on-demand option on the Buyback command. Info such as "current fee" or "time remaining" are available now. Reviewed several cases where non-owned items would get stacked with owner-tagged items. Added Door support for Happyville, Crimsonwood Keep. Added worldmap tooltip support for some maps in Masteria's C. Keep and H. House. Added Masteria region to the world map. C. Keep interiors no longer relocates players to entrance after actions such as logout. Overhauled minigame mechanics: from player boxes tooltip and in-match improvements to deploy different minigame types, accordingly with item description or player choice. Fixed Amoria outskirts not relocating players to city after getting KO'ed. Fixed issues with pets, rings and cash items being assigned the same cash unique ids leading to some quirks on the cash shop inventory. Fixed an issue with the recently added HP/MP ratio update, arbitrarily taking off 1 point in certain cases. Answer positions on the explorer's 3rd job quiz are now randomed. Fixed several issues that showed up when the bcrypt system is disabled. DOT from maps such as El Nath and Aqua Road now procs at a 5sec interval, GMS-like. Improved performance of Whodrops and Search commands. Concurrently protected player interaction handlers, thus mitigating several exploits on these lines. Adjusted several expedition timers, such as Horntail, now having a more sane deadline. Concurrently protected chair modules. Fixed "seduce" debuff not working on chairs.
This commit is contained in:
+12
-4
@@ -11,13 +11,17 @@
|
|||||||
/tools/MapleArrowFetcher/dist/
|
/tools/MapleArrowFetcher/dist/
|
||||||
/tools/MapleArrowFetcher/nbproject/
|
/tools/MapleArrowFetcher/nbproject/
|
||||||
|
|
||||||
/tools/MapleBossHpBarFetcher/nbproject/
|
|
||||||
/tools/MapleBossHpBarFetcher/build/
|
/tools/MapleBossHpBarFetcher/build/
|
||||||
/tools/MapleBossHpBarFetcher/dist/
|
/tools/MapleBossHpBarFetcher/dist/
|
||||||
|
/tools/MapleBossHpBarFetcher/nbproject/
|
||||||
|
|
||||||
/tools/MapleCashDropFetcher/nbproject/
|
|
||||||
/tools/MapleCashDropFetcher/build/
|
/tools/MapleCashDropFetcher/build/
|
||||||
/tools/MapleCashDropFetcher/dist/
|
/tools/MapleCashDropFetcher/dist/
|
||||||
|
/tools/MapleCashDropFetcher/nbproject/
|
||||||
|
|
||||||
|
/tools/MapleCodeCouponGenerator/build/
|
||||||
|
/tools/MapleCodeCouponGenerator/dist/
|
||||||
|
/tools/MapleCodeCouponGenerator/nbproject/
|
||||||
|
|
||||||
/tools/MapleCouponInstaller/build/
|
/tools/MapleCouponInstaller/build/
|
||||||
/tools/MapleCouponInstaller/dist/
|
/tools/MapleCouponInstaller/dist/
|
||||||
@@ -25,7 +29,7 @@
|
|||||||
|
|
||||||
/tools/MapleDojoUpdate/build/
|
/tools/MapleDojoUpdate/build/
|
||||||
/tools/MapleDojoUpdate/dist/
|
/tools/MapleDojoUpdate/dist/
|
||||||
/tools/MapleDojoUpdate/nbproject/private/
|
/tools/MapleDojoUpdate/nbproject/
|
||||||
|
|
||||||
/tools/MapleEquipmentOmnileveler/build/
|
/tools/MapleEquipmentOmnileveler/build/
|
||||||
/tools/MapleEquipmentOmnileveler/dist/
|
/tools/MapleEquipmentOmnileveler/dist/
|
||||||
@@ -59,9 +63,9 @@
|
|||||||
/tools/MapleMobBookUpdate/dist/
|
/tools/MapleMobBookUpdate/dist/
|
||||||
/tools/MapleMobBookUpdate/nbproject/
|
/tools/MapleMobBookUpdate/nbproject/
|
||||||
|
|
||||||
/tools/MapleQuestItemCountFetcher/nbproject/
|
|
||||||
/tools/MapleQuestItemCountFetcher/build/
|
/tools/MapleQuestItemCountFetcher/build/
|
||||||
/tools/MapleQuestItemCountFetcher/dist/
|
/tools/MapleQuestItemCountFetcher/dist/
|
||||||
|
/tools/MapleQuestItemCountFetcher/nbproject/
|
||||||
|
|
||||||
/tools/MapleQuestItemFetcher/build/
|
/tools/MapleQuestItemFetcher/build/
|
||||||
/tools/MapleQuestItemFetcher/dist/
|
/tools/MapleQuestItemFetcher/dist/
|
||||||
@@ -87,5 +91,9 @@
|
|||||||
/tools/MapleSkillMakerReagentIndexer/dist/
|
/tools/MapleSkillMakerReagentIndexer/dist/
|
||||||
/tools/MapleSkillMakerReagentIndexer/nbproject/
|
/tools/MapleSkillMakerReagentIndexer/nbproject/
|
||||||
|
|
||||||
|
/tools/SpiderDropFetcher/build/
|
||||||
|
/tools/SpiderDropFetcher/dist/
|
||||||
|
/tools/SpiderDropFetcher/nbproject/
|
||||||
|
|
||||||
/out
|
/out
|
||||||
*.onetoc2
|
*.onetoc2
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ Client files & general tools: https://drive.google.com/drive/folders/0BzDsHSr-0V
|
|||||||
|
|
||||||
**Important note about localhosts**: these executables are red-flagged by antivirus tools as __potentially malicious softwares__, this happens due to the reverse engineering methods that were applied onto these software artifacts. Those depicted here have been put to use for years already and posed no harm so far, so they are soundly assumed to be safe.
|
**Important note about localhosts**: these executables are red-flagged by antivirus tools as __potentially malicious softwares__, this happens due to the reverse engineering methods that were applied onto these software artifacts. Those depicted here have been put to use for years already and posed no harm so far, so they are soundly assumed to be safe.
|
||||||
|
|
||||||
Recommended localhost: https://hostr.co/m2bVtnizCtmD
|
Latest localhost: https://hostr.co/m2bVtnizCtmD
|
||||||
|
|
||||||
|
The following list, in bottom-up chronological order, holds information regarding all changes that were applied from the starting localhost used in this development. Some lines have a link attached, that will lead you to a snapshot of the localhost at that version of the artifact. Naturally, later versions holds all previous changes along with the proposed changes.
|
||||||
|
|
||||||
**Change log:**
|
**Change log:**
|
||||||
|
|
||||||
@@ -49,10 +51,27 @@ Recommended localhost: https://hostr.co/m2bVtnizCtmD
|
|||||||
* MapleSilver's starting on window-mode.
|
* MapleSilver's starting on window-mode.
|
||||||
|
|
||||||
---
|
---
|
||||||
### Development status
|
### Development information
|
||||||
|
|
||||||
Status: <span style="color:grey">__In development (4th round)__</span>.
|
Status: <span style="color:grey">__In development (4th round)__</span>.
|
||||||
|
|
||||||
|
#### Mission
|
||||||
|
|
||||||
|
With non-profitting means intended, provide nostalgic pre-BB MapleStory players world-wide a quality local server for freestyle entertainment.
|
||||||
|
|
||||||
|
#### Vision
|
||||||
|
|
||||||
|
By taking the v83 MapleStory as the angular stone, incrementally look forward to improve the gaming experience whilst still retaining the "clean v83" conservative ideal. Also, through reviewing distinguished aspects of the server's behavior that could be classified as a potential server threat, in the long run look for ways to improve or even stabilize some of it's uncertain aspects.
|
||||||
|
|
||||||
|
#### Values
|
||||||
|
|
||||||
|
* Autonomy, seek self-improvement for tackling issues head-on;
|
||||||
|
* Adventurous, take no fear of failures on the path of progress;
|
||||||
|
* Light-hearted support, general people out there didn't experience what you've already had;
|
||||||
|
* Humility, no matter how good you are, there's no good in boasting yourself over experiences only a few have had;
|
||||||
|
|
||||||
|
#### Announcements
|
||||||
|
|
||||||
HeavenMS development achieved an acceptable state-of-the-art and will get into a halt. A heartfelt thanks for everyone that contributed in some way for the progress of this server!
|
HeavenMS development achieved an acceptable state-of-the-art and will get into a halt. A heartfelt thanks for everyone that contributed in some way for the progress of this server!
|
||||||
|
|
||||||
Although development is halted, support for fixing features that were implemented here is still up. You can still actively help us improve the server by issuing pull requests with informative details about what's changing.
|
Although development is halted, support for fixing features that were implemented here is still up. You can still actively help us improve the server by issuing pull requests with informative details about what's changing.
|
||||||
@@ -179,6 +198,24 @@ In that case, extract "lolwut.exe" from "lolwut-v0.01.rar" and place it on the M
|
|||||||
|
|
||||||
Important: should the client be refused a connection to the game server, it may be because of firewall issues. Head to the end of this file to proceed in allowing this connection through the computer's firewall. Alternatively, one can deactivate the firewall and try opening the client again.
|
Important: should the client be refused a connection to the game server, it may be because of firewall issues. Head to the end of this file to proceed in allowing this connection through the computer's firewall. Alternatively, one can deactivate the firewall and try opening the client again.
|
||||||
|
|
||||||
|
---
|
||||||
|
### Creating an account and logging in the game
|
||||||
|
|
||||||
|
By default, the server source is set to allow AUTO-REGISTERING. This means that, by simply typing in a "Login ID" and a "Password", you're able to create a new account.
|
||||||
|
|
||||||
|
After creating a character, experiment typing in all-chat "@commands". This will display all available commands for the current GM level your character has.
|
||||||
|
|
||||||
|
To change a character's GM level, make sure that character is not logged in, then:
|
||||||
|
|
||||||
|
* Open MySQL Query Browser;
|
||||||
|
* Double-click "heavenms" schema;
|
||||||
|
* Double click "characters" table;
|
||||||
|
* Execute the selected query;
|
||||||
|
* Mark "Edit" flag on the MySQL Query Browser UI screen;
|
||||||
|
* Locate your character's row on the displayed ResultSet;
|
||||||
|
* Edit your character's GM level;
|
||||||
|
* Hit APPLY CHANGES.
|
||||||
|
|
||||||
---
|
---
|
||||||
### Some notes about WZ/WZ.XML EDITING
|
### Some notes about WZ/WZ.XML EDITING
|
||||||
|
|
||||||
|
|||||||
@@ -68,11 +68,14 @@ Player Social Network:
|
|||||||
* Automated support for Player NPCs and Hall of Fame.
|
* Automated support for Player NPCs and Hall of Fame.
|
||||||
* Protected concurrently and improved the face expression system, guarding from trivial packet spam and exploits.
|
* Protected concurrently and improved the face expression system, guarding from trivial packet spam and exploits.
|
||||||
* All upgradeable non-cash equipments in inventory with level & EXP information available for read by anyone, given proper visibility.
|
* All upgradeable non-cash equipments in inventory with level & EXP information available for read by anyone, given proper visibility.
|
||||||
|
* Further improved the existent minigame mechanics: remarkably checking out for no-item match requests, allowing different omok/matchcard match layouts and status update on the player matchbox tooltips.
|
||||||
|
|
||||||
Cash & Items:
|
Cash & Items:
|
||||||
|
|
||||||
* EXP/DROP/Cosmetic Coupons.
|
* EXP/DROP/Cosmetic Coupons.
|
||||||
* EXP/DROP coupons now appears as a buff effect when on active time.
|
* EXP/DROP coupons now appears as a buff effect when on active time.
|
||||||
|
* Code coupons functional, with support for multiple items on the same code.
|
||||||
|
* Merged unique ids for pets, rings and cash items, thus solving some cash shop inventory issues.
|
||||||
* Great deal of cash items functional.
|
* Great deal of cash items functional.
|
||||||
* MapleTV mechanics stabilized and separated by world.
|
* MapleTV mechanics stabilized and separated by world.
|
||||||
* GMS-esque omok/match card drop chances.
|
* GMS-esque omok/match card drop chances.
|
||||||
@@ -80,7 +83,7 @@ Cash & Items:
|
|||||||
* Inventory system properly checks for item slot free space and ownership.
|
* Inventory system properly checks for item slot free space and ownership.
|
||||||
* Storage with "Arrange Items" feature functional.
|
* Storage with "Arrange Items" feature functional.
|
||||||
* Close-quarters evaluation mode for items (sandbox).
|
* Close-quarters evaluation mode for items (sandbox).
|
||||||
* Further improved Karma scissors mechanics.
|
* Further improved Karma scissors & Untradeable items mechanics.
|
||||||
* Spikes on shoes.
|
* Spikes on shoes.
|
||||||
* Vega's spell.
|
* Vega's spell.
|
||||||
* Owl of Minerva.
|
* Owl of Minerva.
|
||||||
@@ -116,6 +119,8 @@ Monsters, Maps & Reactors:
|
|||||||
* Updated many scripted portals not implementing SFX properly.
|
* Updated many scripted portals not implementing SFX properly.
|
||||||
* Updated Crimsonwood, World Tour, Nihal Desert and Neo City, enabling quest completion and game progression in these areas.
|
* Updated Crimsonwood, World Tour, Nihal Desert and Neo City, enabling quest completion and game progression in these areas.
|
||||||
* Added world maps for Mushroom Castle, World Tour (Singapore, Malaysia and Zipangu) & Ellin Forest areas.
|
* Added world maps for Mushroom Castle, World Tour (Singapore, Malaysia and Zipangu) & Ellin Forest areas.
|
||||||
|
* Added World Tour and Masteria continents in the world map.
|
||||||
|
* Reviewed World Map's town/field tooltips and links from the main world map and Masteria region.
|
||||||
* Giant Cake (anniversary-themed boss) drops Maple equipments, Maple scrolls, summoning bags and many more interesting items.
|
* Giant Cake (anniversary-themed boss) drops Maple equipments, Maple scrolls, summoning bags and many more interesting items.
|
||||||
|
|
||||||
PQ potentials:
|
PQ potentials:
|
||||||
@@ -182,13 +187,14 @@ Custom NPCs:
|
|||||||
* Donation Box: automatized item-buyer.
|
* Donation Box: automatized item-buyer.
|
||||||
* Coco & Ace of Hearts: C. scroll crafters.
|
* Coco & Ace of Hearts: C. scroll crafters.
|
||||||
|
|
||||||
Admin/GM commands:
|
Server Commands:
|
||||||
|
|
||||||
* Server commands layered by GM levels.
|
* Server commands layered by GM levels.
|
||||||
* Spawn Zakum/Horntail/Pinkbean.
|
* Spawn Zakum/Horntail/Pinkbean.
|
||||||
* Several new commands.
|
* Several new commands.
|
||||||
* Rank command highlighting users either by world or server-wide.
|
* Rank command highlighting users either by world or server-wide.
|
||||||
* Revamped command files layout -- thanks Arthur L.
|
* Revamped command files layout -- thanks Arthur L.
|
||||||
|
* Optimized Search command, caching search range contents and added map search functionality.
|
||||||
|
|
||||||
External tools:
|
External tools:
|
||||||
|
|
||||||
|
|||||||
+61
-7
@@ -1276,30 +1276,30 @@ Otimizado função goto, agora não mais gerando mapas de cidade/mapid a todo us
|
|||||||
Melhorado função de disconnect do MapleClient, evitando múltiplos envios de dados do jogador à DB.
|
Melhorado função de disconnect do MapleClient, evitando múltiplos envios de dados do jogador à DB.
|
||||||
Desenhado (todo conteúdo de imagens creditado à Nexon) e implementado novos mapas-mundi referente a regiões de M. Shrine, Showa, CBD e Metropolis/Kampung.
|
Desenhado (todo conteúdo de imagens creditado à Nexon) e implementado novos mapas-mundi referente a regiões de M. Shrine, Showa, CBD e Metropolis/Kampung.
|
||||||
|
|
||||||
03 Agosto 2018,
|
03 Setembro 2018,
|
||||||
Implementado buffs inexpiráveis.
|
Implementado buffs inexpiráveis.
|
||||||
Corrigido comando resetStats não levando em conta AP's atuais dos jogadores.
|
Corrigido comando resetStats não levando em conta AP's atuais dos jogadores.
|
||||||
Corrigido novo sistema gerenciador de loots removendo a possibilidade de conseguir novos itens de quest após coleta do primeiro item.
|
Corrigido novo sistema gerenciador de loots removendo a possibilidade de conseguir novos itens de quest após coleta do primeiro item.
|
||||||
|
|
||||||
04 Agosto 2018,
|
04 Setembro 2018,
|
||||||
Corrigido um flicker na animação do efeito da skill Hurricane.
|
Corrigido um flicker na animação do efeito da skill Hurricane.
|
||||||
Ajustado MapleSessionCoordinator, agora verificando HWID's ao invés de contar somente com o remote IP, evitando negação de serviço para usuários de VPNs.
|
Ajustado MapleSessionCoordinator, agora verificando HWID's ao invés de contar somente com o remote IP, evitando negação de serviço para usuários de VPNs.
|
||||||
Corrigido dispel normal incorretamente mostrando efeitos aleatórios a outros jogadores, issue apontado por Thora.
|
Corrigido dispel normal incorretamente mostrando efeitos aleatórios a outros jogadores, issue apontado por Thora.
|
||||||
Corrigido change job não mostrando efeito a outros jogadores.
|
Corrigido change job não mostrando efeito a outros jogadores.
|
||||||
Corrigido valores incorretos sendo retirado de jogadores para expansão de guild, issue apontado por Thora.
|
Corrigido valores incorretos sendo retirado de jogadores para expansão de guild, issue apontado por Thora.
|
||||||
|
|
||||||
05 Agosto 2018,
|
05 Setembro 2018,
|
||||||
Adicionado world map em Ellin Forest.
|
Adicionado world map em Ellin Forest.
|
||||||
Protegido concorrentemente sistema de fames.
|
Protegido concorrentemente sistema de fames.
|
||||||
Adicionado ganho de quest points para jogadores que participam de PQs. Reformulado sistema de quest points para viabilizar a nova feature.
|
Adicionado ganho de quest points para jogadores que participam de PQs. Reformulado sistema de quest points para viabilizar a nova feature.
|
||||||
Otimizado método de ganho de experiência em equipamentos, agora devidamente cacheado e sem busca em strings no processo.
|
Otimizado método de ganho de experiência em equipamentos, agora devidamente cacheado e sem busca em strings no processo.
|
||||||
|
|
||||||
08 Agosto 2018,
|
08 Setembro 2018,
|
||||||
MapleServerHandler agora é devidamente deregistrado ao finalizar uma instância de channel, eliminando possível foco de memory leak.
|
MapleServerHandler agora é devidamente deregistrado ao finalizar uma instância de channel, eliminando possível foco de memory leak.
|
||||||
Funções playerDead e playerRevive são agora opcionais em EIM scripts.
|
Funções playerDead e playerRevive são agora opcionais em EIM scripts.
|
||||||
Nova ferramenta: MapleEquipmentOmnileveler. Permite adicionar e atualizar nodos referentes a níveis para todos os equipamentos. Em jogo, essa adição permite jogadores a ver nível de qualquer equipamento do jogo.
|
Nova ferramenta: MapleEquipmentOmnileveler. Permite adicionar e atualizar nodos referentes a níveis para todos os equipamentos. Em jogo, essa adição permite jogadores a ver nível de qualquer equipamento do jogo.
|
||||||
|
|
||||||
09 - 10 Agosto 2018,
|
09 - 10 Setembro 2018,
|
||||||
Adicionado cálculo de MP ao realizar ataques de mobs.
|
Adicionado cálculo de MP ao realizar ataques de mobs.
|
||||||
Aplicado vários pequenos ajustes no handler que lida com movimentação de mobs, procurando assim reduzir ruidos no fluxo do jogo (e.g. mob caindo de foothold).
|
Aplicado vários pequenos ajustes no handler que lida com movimentação de mobs, procurando assim reduzir ruidos no fluxo do jogo (e.g. mob caindo de foothold).
|
||||||
Corrigido schedules de event instances sendo chamados após finalização da mesma, levando locks já liberados a serem chamados inesperadamente.
|
Corrigido schedules de event instances sendo chamados após finalização da mesma, levando locks já liberados a serem chamados inesperadamente.
|
||||||
@@ -1307,7 +1307,7 @@ Corrigido casos onde jogadores poderiam requisitar instanciação de uma nova PQ
|
|||||||
Aplicado reformatação geral no Character.wz, adicionando nodos de level para todos os equipamentos do jogo. Tal mudança permite que todos os equipamentos exponham nível e experiência em todos os equipamentos no inventário.
|
Aplicado reformatação geral no Character.wz, adicionando nodos de level para todos os equipamentos do jogo. Tal mudança permite que todos os equipamentos exponham nível e experiência em todos os equipamentos no inventário.
|
||||||
Implementado cálculo de experiência no lado do servidor que permite mostrar adequadamente EXP dos equipamentos no lado do cliente.
|
Implementado cálculo de experiência no lado do servidor que permite mostrar adequadamente EXP dos equipamentos no lado do cliente.
|
||||||
|
|
||||||
11 - 19 Agosto 2018,
|
11 - 19 Setembro 2018,
|
||||||
Corrigido MP Recovery skill não atuando segundo descrição, além de matando jogador com pouco HP disponível.
|
Corrigido MP Recovery skill não atuando segundo descrição, além de matando jogador com pouco HP disponível.
|
||||||
Refatorado completamente acessos de stats no código do server.
|
Refatorado completamente acessos de stats no código do server.
|
||||||
Refatorado check de Berserk sendo chamado em múltiplas seções do código.
|
Refatorado check de Berserk sendo chamado em múltiplas seções do código.
|
||||||
@@ -1326,5 +1326,59 @@ Corrigido alliances retendo informações de guilds que foram desfeitas na DB.
|
|||||||
Corrigido alliances não salvando nomes de ranks na DB ao serem criadas.
|
Corrigido alliances não salvando nomes de ranks na DB ao serem criadas.
|
||||||
Adicionado suporte para doors na região de Mushroom Castle.
|
Adicionado suporte para doors na região de Mushroom Castle.
|
||||||
|
|
||||||
24 Agosto 2018,
|
24 Setembro 2018,
|
||||||
Resolvido pequenas inconsistências entre os XMLs e WZs disponibilizados.
|
Resolvido pequenas inconsistências entre os XMLs e WZs disponibilizados.
|
||||||
|
Alterado "session write" para "announce", agora devidamente utilizando encapsulamento e lidando com sincronização de serviços.
|
||||||
|
|
||||||
|
25 Setembro 2018,
|
||||||
|
Corrigido diversas exceções no cash shop congelando próximas ações dos jogadores, somente ficando disponível após sair do mesmo.
|
||||||
|
Reimplementado sistema de code coupons no cash shop.
|
||||||
|
Removido skills Teleport e Super Dragon Roar redundantes do job SuperGM (jobid 910).
|
||||||
|
Adicionado informações detalhadas do estado corrente do buyback, em forma de comando.
|
||||||
|
Corrigido desligamento de channel com jogadores dentro do cash shop levando o sistema a lançar algumas exceções.
|
||||||
|
|
||||||
|
26 Setembro 2018,
|
||||||
|
Aprimorado code coupons, agora permitindo entrega de vários itens no mesmo código.
|
||||||
|
Revisado uso de addById no código, não permitindo adicionar itens limpos em slots de itens que possuem marcação de dono.
|
||||||
|
Implementado automatização de geração de coupon codes baseado em templates, utilizando arquivo XML para pegar os parâmetros.
|
||||||
|
|
||||||
|
29 Setembro 2018,
|
||||||
|
Corrigido Ereve faltando suporte para um Door portal.
|
||||||
|
Adicionado suporte de Doors para Happyville e Crimsonwood Keep.
|
||||||
|
Melhorado aspectos do world map da região de Masteria, adicionando interiores de Crimsonwood Keep no mapa e tooltip para interiores de Haunted House no mapa de Masteria.
|
||||||
|
Aprimorado região interior de Crimsonwood Keep, não mais reposicionando jogadores com a funcionalidade forcedReturn do WZ.
|
||||||
|
Corrigido arredores de Amoria não retornando jogadores para a cidade ao ressucitar pelo método usual.
|
||||||
|
Corrigido petids e ringids misturando valores com cashids de itens comuns, potencialmente causando problemas com os inventários do jogador e do cash shop da conta do mesmo.
|
||||||
|
|
||||||
|
30 Setembro 2018,
|
||||||
|
Adicionado região de Masteria no World Map.
|
||||||
|
Corrigido ligação de Ludibrium para Orbis não sendo mostrado corretamente.
|
||||||
|
Melhorado ratio update de HP/MP, agora memorizando ratio recentes ao efetuar ações como modificar status do inventário de itens equipados, entre outros.
|
||||||
|
|
||||||
|
01 - 03 Outubro 2018,
|
||||||
|
Corrigido diversos problemas com o sistema de login quando o uso do bcrypt está desativado.
|
||||||
|
Implementado/melhorado diversas mecânicas dos minigames (do aspecto dos tooltips dos boxes às pontuações visiveis dentro da sala e sistema de pontuação interno único), tornando agora finalmente viável a jogabilidade estendida dessa funcionalidade.
|
||||||
|
Adicionado server flag para evitar levelup em equipamentos de cash.
|
||||||
|
Melhorado verificação de itens untradeable em vários pontos do código, agora avaliando também status de Karma.
|
||||||
|
Adicionado funcionalidade de pesquisa de mapas no comando Search.
|
||||||
|
Otimizado comando Search, agora cacheando dados para as pesquisas.
|
||||||
|
Corrigido pequenas inconsistências com HPMP ratio recém implementado.
|
||||||
|
Revisado drop chance de vários itens de quest e diversos ETC drops de mobs de nível baixo.
|
||||||
|
Revisado descrições de várias skills de GM.
|
||||||
|
|
||||||
|
04 Outubro 2018,
|
||||||
|
Prequest de Zakum agora recompensa 5 Eye of Fire, valor oficial.
|
||||||
|
Modificado script de quiz do 3rd job, agora randomizando posicionamento das respostas.
|
||||||
|
Modificado damage-over-time em mapas como arredores de El Nath e Aqua Road, agora dando dano a cada 5 segundos, como previsto na versão oficial.
|
||||||
|
Corrigido comando Whodrops potencialmente lagando o servidor se comando for spammado por jogadores.
|
||||||
|
Protegido concorrentemente handler de interação de jogadores (trades, player shops, minigames, entre outros).
|
||||||
|
Melhorado checagem de acesso concorrente em alguns handlers, agora utilizando semáforos para fazer a filtragem de requisições a esses handlers.
|
||||||
|
Revertido pet pickup para permitindo coletar itens indiscriminadamente de ataque. Causa de situações onde pet pickup evita ação de ataque de jogador não está claro.
|
||||||
|
Modificado timers para diversas expedições, agora com duração máxima entre 1h30 a 2h.
|
||||||
|
|
||||||
|
08 Outubro 2018,
|
||||||
|
Protegido concorrentemente módulos de chairs.
|
||||||
|
|
||||||
|
09 Outubro 2018,
|
||||||
|
Corrigido disease seduce não funcionando da forma esperada quando jogador está sentado.
|
||||||
|
Movido Dropspider para fora do código-fonte do server, agora estando como uma ferramenta externa.
|
||||||
+4
-4
@@ -903,10 +903,10 @@
|
|||||||
2048003 - Scroll for Pet Equip. for Jump - Improves jump on pet equip.\nSuccess rate:100%, jump+1
|
2048003 - Scroll for Pet Equip. for Jump - Improves jump on pet equip.\nSuccess rate:100%, jump+1
|
||||||
2048004 - Scroll for Pet Equip. for Jump - Improves jump on pet equip.\nSuccess rate:60%, jump+2. The success rate of this scroll can be enhanced by Vega's Spell.
|
2048004 - Scroll for Pet Equip. for Jump - Improves jump on pet equip.\nSuccess rate:60%, jump+2. The success rate of this scroll can be enhanced by Vega's Spell.
|
||||||
2048005 - Scroll for Pet Equip. for Jump - Improves jump on pet equip.\nSuccess rate:10%, jump+3. The success rate of this scroll can be enhanced by Vega's Spell.
|
2048005 - Scroll for Pet Equip. for Jump - Improves jump on pet equip.\nSuccess rate:10%, jump+3. The success rate of this scroll can be enhanced by Vega's Spell.
|
||||||
2048006 - Scroll for Speed for Pet Equip. - Improves speed on Pet Equip. nSuccess rate:65%, speed+2
|
2048006 - Scroll for Pet Equip. for Speed - Improves speed on Pet Equip. nSuccess rate:65%, speed+2
|
||||||
2048007 - Scroll for Speed for Pet Equip. - Improves speed on Pet Equip. nSuccess rate:15%, speed+3
|
2048007 - Scroll for Pet Equip. for Speed - Improves speed on Pet Equip. nSuccess rate:15%, speed+3
|
||||||
2048008 - Scroll for jump for Pet Equip. - Improves jump on Pet equip. nSuccess rate:65%, jump+2
|
2048008 - Scroll for Pet Equip. for Jump - Improves jump on Pet equip. nSuccess rate:65%, jump+2
|
||||||
2048009 - Scroll for jump for Pet Equip. - Improves jump on Pet equip. nSuccess rate:15%, jump+3
|
2048009 - Scroll for Pet Equip. for Jump - Improves jump on Pet equip. nSuccess rate:15%, jump+3
|
||||||
2048010 - Scroll for Pet Equip. for STR 60% - Improves strength on pet equipments.\nSuccess rate:60%, STR+1. The success rate of this scroll can be enhanced by Vega's Spell.
|
2048010 - Scroll for Pet Equip. for STR 60% - Improves strength on pet equipments.\nSuccess rate:60%, STR+1. The success rate of this scroll can be enhanced by Vega's Spell.
|
||||||
2048011 - Scroll for Pet Equip. for INT 60% - Improves intelligence on pet equipments.\nSuccess rate:60%, INT+1. The success rate of this scroll can be enhanced by Vega's Spell.
|
2048011 - Scroll for Pet Equip. for INT 60% - Improves intelligence on pet equipments.\nSuccess rate:60%, INT+1. The success rate of this scroll can be enhanced by Vega's Spell.
|
||||||
2048012 - Scroll for Pet Equip. for DEX 60% - Improves dexterity on pet equipments.\nSuccess rate:60%, DEX+1. The success rate of this scroll can be enhanced by Vega's Spell.
|
2048012 - Scroll for Pet Equip. for DEX 60% - Improves dexterity on pet equipments.\nSuccess rate:60%, DEX+1. The success rate of this scroll can be enhanced by Vega's Spell.
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
compile.on.save=true
|
compile.on.save=true
|
||||||
do.depend=false
|
do.depend=false
|
||||||
do.jar=true
|
do.jar=true
|
||||||
file.reference.mina-core-2.0.7.jar=C:\\Nexon\\HeavenMS\\cores\\mina-core-2.0.7.jar
|
|
||||||
file.reference.mysql-connector-java-bin.jar=C:\\Nexon\\HeavenMS\\cores\\mysql-connector-java-bin.jar
|
|
||||||
file.reference.slf4j-api-1.6.6.jar=C:\\Nexon\\HeavenMS\\cores\\slf4j-api-1.6.6.jar
|
|
||||||
file.reference.slf4j-jdk14-1.7.5.jar=C:\\Nexon\\HeavenMS\\cores\\slf4j-jdk14-1.7.5.jar
|
|
||||||
javac.debug=true
|
javac.debug=true
|
||||||
javadoc.preview=true
|
javadoc.preview=true
|
||||||
user.properties.file=C:\\Users\\RonanLana\\AppData\\Roaming\\NetBeans\\8.0.2\\build.properties
|
user.properties.file=C:\\Users\\RonanLana\\AppData\\Roaming\\NetBeans\\8.0.2\\build.properties
|
||||||
|
|||||||
@@ -30,20 +30,20 @@ endorsed.classpath=
|
|||||||
excludes=
|
excludes=
|
||||||
file.reference.HikariCP-java7-2.4.12.jar=cores/HikariCP-java7-2.4.12.jar
|
file.reference.HikariCP-java7-2.4.12.jar=cores/HikariCP-java7-2.4.12.jar
|
||||||
file.reference.MapleSolaxia-src=src
|
file.reference.MapleSolaxia-src=src
|
||||||
file.reference.mina-core-2.0.7.jar=cores\\mina-core-2.0.7.jar
|
file.reference.mina-core-2.0.7.jar=cores/mina-core-2.0.7.jar
|
||||||
file.reference.mysql-connector-java-bin.jar=cores\\mysql-connector-java-bin.jar
|
file.reference.mysql-connector-java-bin.jar=cores/mysql-connector-java-bin.jar
|
||||||
file.reference.slf4j-api-1.6.6.jar=cores\\slf4j-api-1.6.6.jar
|
file.reference.slf4j-api-1.6.6.jar=cores/slf4j-api-1.6.6.jar
|
||||||
file.reference.slf4j-jdk14-1.7.5.jar=cores\\slf4j-jdk14-1.7.5.jar
|
file.reference.slf4j-jdk14-1.7.5.jar=cores/slf4j-jdk14-1.7.5.jar
|
||||||
includes=**
|
includes=**
|
||||||
jar.archive.disabled=${jnlp.enabled}
|
jar.archive.disabled=${jnlp.enabled}
|
||||||
jar.compress=true
|
jar.compress=true
|
||||||
jar.index=${jnlp.enabled}
|
jar.index=${jnlp.enabled}
|
||||||
javac.classpath=\
|
javac.classpath=\
|
||||||
|
${file.reference.HikariCP-java7-2.4.12.jar}:\
|
||||||
${file.reference.mina-core-2.0.7.jar}:\
|
${file.reference.mina-core-2.0.7.jar}:\
|
||||||
${file.reference.mysql-connector-java-bin.jar}:\
|
${file.reference.mysql-connector-java-bin.jar}:\
|
||||||
${file.reference.slf4j-api-1.6.6.jar}:\
|
${file.reference.slf4j-api-1.6.6.jar}:\
|
||||||
${file.reference.slf4j-jdk14-1.7.5.jar}:\
|
${file.reference.slf4j-jdk14-1.7.5.jar}
|
||||||
${file.reference.HikariCP-java7-2.4.12.jar}
|
|
||||||
# Space-separated list of extra javac options
|
# Space-separated list of extra javac options
|
||||||
javac.compilerargs=
|
javac.compilerargs=
|
||||||
javac.deprecation=false
|
javac.deprecation=false
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 0);
|
player.changeMap(entryMap, 0);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 0);
|
player.changeMap(entryMap, 0);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 0);
|
player.changeMap(entryMap, 0);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 0);
|
player.changeMap(entryMap, 0);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 0);
|
player.changeMap(entryMap, 0);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 0);
|
player.changeMap(entryMap, 0);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(map, map.getPortal(0));
|
player.changeMap(map, map.getPortal(0));
|
||||||
|
|
||||||
//TODO: hold time across map changes
|
//TODO: hold time across map changes
|
||||||
//player.getClient().getSession().write(tools.MaplePacketCreator.getClock(1800));
|
//player.getClient().announce(tools.MaplePacketCreator.getClock(1800));
|
||||||
}
|
}
|
||||||
|
|
||||||
function playerDead(eim, player) {
|
function playerDead(eim, player) {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 2);
|
player.changeMap(entryMap, 2);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 1);
|
player.changeMap(entryMap, 1);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 1);
|
player.changeMap(entryMap, 1);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(entryMap, 0);
|
player.changeMap(entryMap, 0);
|
||||||
em.setProperty("noEntry","true");
|
em.setProperty("noEntry","true");
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ function changedMap(eim, player, mapid) {
|
|||||||
function afterChangedMap(eim, player, mapid) {
|
function afterChangedMap(eim, player, mapid) {
|
||||||
if (mapid == 990000100) {
|
if (mapid == 990000100) {
|
||||||
var texttt = "So, here is the brief. You guys should be warned that, once out on the fortress outskirts, anyone that would not be equipping the #b#t1032033##k will die instantly due to the deteriorated state of the air around there. That being said, once your team moves out, make sure to #bhit the glowing rocks#k in that region and #bequip the dropped item#k before advancing stages. That will protect you thoroughly from the air sickness. Good luck!";
|
var texttt = "So, here is the brief. You guys should be warned that, once out on the fortress outskirts, anyone that would not be equipping the #b#t1032033##k will die instantly due to the deteriorated state of the air around there. That being said, once your team moves out, make sure to #bhit the glowing rocks#k in that region and #bequip the dropped item#k before advancing stages. That will protect you thoroughly from the air sickness. Good luck!";
|
||||||
player.getClient().getSession().write(Packages.tools.MaplePacketCreator.getNPCTalk(9040000, /*(byte)*/ 0, texttt, "00 00", /*(byte)*/ 0));
|
player.getClient().announce(Packages.tools.MaplePacketCreator.getNPCTalk(9040000, /*(byte)*/ 0, texttt, "00 00", /*(byte)*/ 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ function playerEntry(eim, player) {
|
|||||||
onRide = eim.getMapFactory().getMap(birdRide[myRide]);
|
onRide = eim.getMapFactory().getMap(birdRide[myRide]);
|
||||||
player.changeMap(onRide, onRide.getPortal(0));
|
player.changeMap(onRide, onRide.getPortal(0));
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(rideTime / 1000));
|
player.getClient().announce(MaplePacketCreator.getClock(rideTime / 1000));
|
||||||
eim.schedule("timeOut", rideTime);
|
eim.schedule("timeOut", rideTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ var clearMap = 240050600;
|
|||||||
var minMapId = 240060000;
|
var minMapId = 240060000;
|
||||||
var maxMapId = 240060200;
|
var maxMapId = 240060200;
|
||||||
|
|
||||||
var eventTime = 15; // 15 minutes
|
var eventTime = 120; // 120 minutes
|
||||||
|
|
||||||
var lobbyRange = [0, 0];
|
var lobbyRange = [0, 0];
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ function playerEntry(eim, player) {
|
|||||||
onRide = eim.getMapFactory().getMap(trainRide[myRide]);
|
onRide = eim.getMapFactory().getMap(trainRide[myRide]);
|
||||||
player.changeMap(onRide, onRide.getPortal(0));
|
player.changeMap(onRide, onRide.getPortal(0));
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(rideTime / 1000));
|
player.getClient().announce(MaplePacketCreator.getClock(rideTime / 1000));
|
||||||
player.getClient().getSession().write(MaplePacketCreator.earnTitleMessage("The next stop is at Kerning " + (myRide == 0 ? "Square" : "Subway") + " Station. The exit is to your left."));
|
player.getClient().announce(MaplePacketCreator.earnTitleMessage("The next stop is at Kerning " + (myRide == 0 ? "Square" : "Subway") + " Station. The exit is to your left."));
|
||||||
eim.schedule("timeOut", rideTime);
|
eim.schedule("timeOut", rideTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ importPackage(Packages.tools);
|
|||||||
importPackage(Packages.server.life);
|
importPackage(Packages.server.life);
|
||||||
|
|
||||||
var minPlayers = 1;
|
var minPlayers = 1;
|
||||||
var eventTime = 10;
|
var eventTime = 10; // 10 minutes
|
||||||
var entryMap = 106021402;
|
var entryMap = 106021402;
|
||||||
var exitMap = 106021600;
|
var exitMap = 106021600;
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ function playerEntry(eim, player){
|
|||||||
var pm = MapleLifeFactory.getMonster(3300008);
|
var pm = MapleLifeFactory.getMonster(3300008);
|
||||||
weddinghall.spawnMonsterOnGroundBelow(pm, new Packages.java.awt.Point(472, 27));
|
weddinghall.spawnMonsterOnGroundBelow(pm, new Packages.java.awt.Point(472, 27));
|
||||||
|
|
||||||
player.getClient().getSession().write(MaplePacketCreator.getClock(eventTime * 60));
|
player.getClient().announce(MaplePacketCreator.getClock(eventTime * 60));
|
||||||
eim.startEventTimer(eventTime * 60000);
|
eim.startEventTimer(eventTime * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ function playerEntry(eim, player) {
|
|||||||
player.changeMap(map, map.getPortal(0));
|
player.changeMap(map, map.getPortal(0));
|
||||||
|
|
||||||
var texttt = "Hi, my name is Eak, the Chamberlain of the Goddess. Don't be alarmed; you won't be able to see me right now. Back when the Goddess turned into a block of stone, I simultaneously lost my own power. If you gather up the power of the Magic Cloud of Orbis, however, then I'll be able to recover my body and re-transform back to my original self. Please collect #b20#k Magic Clouds and bring them back to me. Right now, you'll only see me as a tiny, flickering light.";
|
var texttt = "Hi, my name is Eak, the Chamberlain of the Goddess. Don't be alarmed; you won't be able to see me right now. Back when the Goddess turned into a block of stone, I simultaneously lost my own power. If you gather up the power of the Magic Cloud of Orbis, however, then I'll be able to recover my body and re-transform back to my original self. Please collect #b20#k Magic Clouds and bring them back to me. Right now, you'll only see me as a tiny, flickering light.";
|
||||||
player.getClient().getSession().write(Packages.tools.MaplePacketCreator.getNPCTalk(2013001, /*(byte)*/ 0, texttt, "00 00", /*(byte)*/ 0));
|
player.getClient().announce(Packages.tools.MaplePacketCreator.getNPCTalk(2013001, /*(byte)*/ 0, texttt, "00 00", /*(byte)*/ 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
function scheduledTimeout(eim) {
|
function scheduledTimeout(eim) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ var clearMap = 270050300;
|
|||||||
var minMapId = 270050100;
|
var minMapId = 270050100;
|
||||||
var maxMapId = 270050300;
|
var maxMapId = 270050300;
|
||||||
|
|
||||||
var eventTime = 100; // 100 minutes
|
var eventTime = 140; // 140 minutes
|
||||||
|
|
||||||
var lobbyRange = [0, 0];
|
var lobbyRange = [0, 0];
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
importPackage(Packages.tools);
|
importPackage(Packages.tools);
|
||||||
|
|
||||||
var exitMap;
|
var exitMap;
|
||||||
var startMap;
|
var entryMap;
|
||||||
var otherMap;
|
var otherMap;
|
||||||
var minPlayers = 1;
|
var minPlayers = 1;
|
||||||
var fightTime = 60;
|
var fightTime = 60;
|
||||||
@@ -30,7 +30,7 @@ var timer = 1000 * 60 * fightTime;
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
exitMap = em.getChannelServer().getMapFactory().getMap(103040400);
|
exitMap = em.getChannelServer().getMapFactory().getMap(103040400);
|
||||||
startMap = em.getChannelServer().getMapFactory().getMap(103040410);
|
entryMap = em.getChannelServer().getMapFactory().getMap(103040410);
|
||||||
otherMap = em.getChannelServer().getMapFactory().getMap(103040420);
|
otherMap = em.getChannelServer().getMapFactory().getMap(103040420);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ function setup() {
|
|||||||
function afterSetup(eim) {}
|
function afterSetup(eim) {}
|
||||||
|
|
||||||
function respawn(eim) {
|
function respawn(eim) {
|
||||||
var map = eim.getMapInstance(startMap.getId());
|
var map = eim.getMapInstance(entryMap.getId());
|
||||||
var map2 = eim.getMapInstance(otherMap.getId());
|
var map2 = eim.getMapInstance(otherMap.getId());
|
||||||
map.allowSummonState(true);
|
map.allowSummonState(true);
|
||||||
map2.allowSummonState(true);
|
map2.allowSummonState(true);
|
||||||
@@ -55,7 +55,7 @@ function respawn(eim) {
|
|||||||
|
|
||||||
|
|
||||||
function playerEntry(eim, player) {
|
function playerEntry(eim, player) {
|
||||||
var amplifierMap = eim.getMapInstance(startMap.getId());
|
var amplifierMap = eim.getMapInstance(entryMap.getId());
|
||||||
player.changeMap(amplifierMap);
|
player.changeMap(amplifierMap);
|
||||||
eim.schedule("timeOut", timer);
|
eim.schedule("timeOut", timer);
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ function playerExit(eim, player) {
|
|||||||
function moveMap(eim, player) {
|
function moveMap(eim, player) {
|
||||||
if (player.getMap().getId() == exitMap.getId()) {
|
if (player.getMap().getId() == exitMap.getId()) {
|
||||||
removePlayer(eim, player);
|
removePlayer(eim, player);
|
||||||
player.getClient().getSession().write(MaplePacketCreator.removeClock());
|
player.getClient().announce(MaplePacketCreator.removeClock());
|
||||||
eim.dispose();
|
eim.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
importPackage(Packages.tools);
|
importPackage(Packages.tools);
|
||||||
|
|
||||||
var exitMap;
|
var exitMap;
|
||||||
var startMap;
|
var entryMap;
|
||||||
var otherMap;
|
var otherMap;
|
||||||
var minPlayers = 1;
|
var minPlayers = 1;
|
||||||
var fightTime = 30;
|
var fightTime = 30;
|
||||||
@@ -30,7 +30,7 @@ var timer = 1000 * 60 * fightTime;
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
exitMap = em.getChannelServer().getMapFactory().getMap(103040400);
|
exitMap = em.getChannelServer().getMapFactory().getMap(103040400);
|
||||||
startMap = em.getChannelServer().getMapFactory().getMap(103040440);
|
entryMap = em.getChannelServer().getMapFactory().getMap(103040440);
|
||||||
otherMap = em.getChannelServer().getMapFactory().getMap(103040450);
|
otherMap = em.getChannelServer().getMapFactory().getMap(103040450);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ function setup() {
|
|||||||
function afterSetup(eim) {}
|
function afterSetup(eim) {}
|
||||||
|
|
||||||
function respawn(eim) {
|
function respawn(eim) {
|
||||||
var map = eim.getMapInstance(startMap.getId());
|
var map = eim.getMapInstance(entryMap.getId());
|
||||||
var map2 = eim.getMapInstance(otherMap.getId());
|
var map2 = eim.getMapInstance(otherMap.getId());
|
||||||
map.allowSummonState(true);
|
map.allowSummonState(true);
|
||||||
map2.allowSummonState(true);
|
map2.allowSummonState(true);
|
||||||
@@ -55,7 +55,7 @@ function respawn(eim) {
|
|||||||
|
|
||||||
|
|
||||||
function playerEntry(eim, player) {
|
function playerEntry(eim, player) {
|
||||||
var amplifierMap = eim.getMapInstance(startMap.getId());
|
var amplifierMap = eim.getMapInstance(entryMap.getId());
|
||||||
player.changeMap(amplifierMap);
|
player.changeMap(amplifierMap);
|
||||||
eim.schedule("timeOut", timer);
|
eim.schedule("timeOut", timer);
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ function playerExit(eim, player) {
|
|||||||
function moveMap(eim, player) {
|
function moveMap(eim, player) {
|
||||||
if (player.getMap().getId() == exitMap.getId()) {
|
if (player.getMap().getId() == exitMap.getId()) {
|
||||||
removePlayer(eim, player);
|
removePlayer(eim, player);
|
||||||
player.getClient().getSession().write(MaplePacketCreator.removeClock());
|
player.getClient().announce(MaplePacketCreator.removeClock());
|
||||||
eim.dispose();
|
eim.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ var clearMap = 211042400;
|
|||||||
var minMapId = 280030000;
|
var minMapId = 280030000;
|
||||||
var maxMapId = 280030000;
|
var maxMapId = 280030000;
|
||||||
|
|
||||||
var eventTime = 60; // 60 minutes
|
var eventTime = 120; // 120 minutes
|
||||||
|
|
||||||
var lobbyRange = [0, 0];
|
var lobbyRange = [0, 0];
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
function start(ms) {
|
function start(ms) {
|
||||||
//var pq = ms.getPyramid();
|
//var pq = ms.getPyramid();
|
||||||
//ms.getPlayer().resetEnteredScript();
|
//ms.getPlayer().resetEnteredScript();
|
||||||
//ms.getClient().getSession().write(MaplePacketCreator.getClock(pq.timer()));
|
//ms.getClient().announce(MaplePacketCreator.getClock(pq.timer()));
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
killing/first/stage
|
killing/first/stage
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ var player;
|
|||||||
function start(ms) {
|
function start(ms) {
|
||||||
player = ms.getPlayer();
|
player = ms.getPlayer();
|
||||||
player.resetEnteredScript();
|
player.resetEnteredScript();
|
||||||
ms.getClient().getSession().write(MaplePacketCreator.showEffect("event/space/start"));
|
ms.getClient().announce(MaplePacketCreator.showEffect("event/space/start"));
|
||||||
player.startMapEffect("Please rescue Gaga within the time limit.", 5120027);
|
player.startMapEffect("Please rescue Gaga within the time limit.", 5120027);
|
||||||
var map = player.getMap();
|
var map = player.getMap();
|
||||||
if (map.getTimeLeft() > 0) {
|
if (map.getTimeLeft() > 0) {
|
||||||
ms.getClient().getSession().write(MaplePacketCreator.getClock(map.getTimeLeft()));
|
ms.getClient().announce(MaplePacketCreator.getClock(map.getTimeLeft()));
|
||||||
} else {
|
} else {
|
||||||
map.addMapTimer(180);
|
map.addMapTimer(180);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ function action(mode, type, selection) {
|
|||||||
if(status == 0){
|
if(status == 0){
|
||||||
cm.sendYesNo("Would you like to leave?");
|
cm.sendYesNo("Would you like to leave?");
|
||||||
}else if(status == 1){
|
}else if(status == 1){
|
||||||
var mapid = cm.getMapId();
|
var mapid = cm.getMapId(), exitid = mapid;
|
||||||
if(mapid == 108010101) cm.getPlayer().changeMap(105040305);
|
if(mapid == 108010101) exitid = 105040305;
|
||||||
else if(mapid == 108010201) cm.getPlayer().changeMap(100040106);
|
else if(mapid == 108010201) exitid = 100040106;
|
||||||
else if(mapid == 108010301) cm.getPlayer().changeMap(105070001);
|
else if(mapid == 108010301) exitid = 105070001;
|
||||||
else if(mapid == 108010401) cm.getPlayer().changeMap(107000402);
|
else if(mapid == 108010401) exitid = 107000402;
|
||||||
else if(mapid == 108010501) cm.getPlayer().changeMap(105070200);
|
else if(mapid == 108010501) exitid = 105070200;
|
||||||
|
|
||||||
|
if (mapid != exitid) cm.getPlayer().changeMap(exitid);
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ function action(mode, type, selection){
|
|||||||
else if (status == 2) {
|
else if (status == 2) {
|
||||||
if (cm.getPlayer().getRemainingSp() > 0)
|
if (cm.getPlayer().getRemainingSp() > 0)
|
||||||
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
||||||
cm.sendNext("Please, use all your SP before contining.");
|
cm.sendNext("Please, use all your SP before continuing.");
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function action(mode, type, selection){
|
|||||||
else if (status == 2) {
|
else if (status == 2) {
|
||||||
if (cm.getPlayer().getRemainingSp() > 0)
|
if (cm.getPlayer().getRemainingSp() > 0)
|
||||||
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
||||||
cm.sendNext("Please, use all your SP before contining.");
|
cm.sendNext("Please, use all your SP before continuing.");
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ function action(mode, type, selection){
|
|||||||
else if (status == 2) {
|
else if (status == 2) {
|
||||||
if (cm.getPlayer().getRemainingSp() > 0)
|
if (cm.getPlayer().getRemainingSp() > 0)
|
||||||
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
||||||
cm.sendNext("Please, use all your SP before contining.");
|
cm.sendNext("Please, use all your SP before continuing.");
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function action(mode, type, selection){
|
|||||||
else if (status == 2) {
|
else if (status == 2) {
|
||||||
if (cm.getPlayer().getRemainingSp() > 0)
|
if (cm.getPlayer().getRemainingSp() > 0)
|
||||||
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
||||||
cm.sendNext("Please, use all your SP before contining.");
|
cm.sendNext("Please, use all your SP before continuing.");
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function action(mode, type, selection){
|
|||||||
else if (status == 2) {
|
else if (status == 2) {
|
||||||
if (cm.getPlayer().getRemainingSp() > 0)
|
if (cm.getPlayer().getRemainingSp() > 0)
|
||||||
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
if (cm.getPlayer().getRemainingSp() > (cm.getLevel() - 70) * 3) {
|
||||||
cm.sendNext("Please, use all your SP before contining.");
|
cm.sendNext("Please, use all your SP before continuing.");
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-6
@@ -39,7 +39,7 @@ var questionTree = [
|
|||||||
//Questions Related to MONSTERS
|
//Questions Related to MONSTERS
|
||||||
["Green Mushroom, Tree Stump, Bubbling, Axe Stump, Octopus, which is highest level of all?", ["Tree Stump", "Bubbling", "Axe Stump", "Octopus", "Green Mushroom"], 2],
|
["Green Mushroom, Tree Stump, Bubbling, Axe Stump, Octopus, which is highest level of all?", ["Tree Stump", "Bubbling", "Axe Stump", "Octopus", "Green Mushroom"], 2],
|
||||||
["Which monster will be seen during the ship trip to Orbis/Ellinia?", ["Werewolf", "Slime", "Crimson Balrog", "Zakum", "Star Pixie"], 2],
|
["Which monster will be seen during the ship trip to Orbis/Ellinia?", ["Werewolf", "Slime", "Crimson Balrog", "Zakum", "Star Pixie"], 2],
|
||||||
["Maple Island doesn't have which following monsters?", ["Shroom", "Blue Snail", "Orange Mushroom", "Red Snail", "Pig"], 4],
|
["Maple Island doesn't have which following monsters?", ["Green Mushroom", "Blue Snail", "Orange Mushroom", "Red Snail", "Pig"], 0],
|
||||||
["Which monster is not at Victoria Island and Sleepywood?", ["Evil Eye", "Sentinel", "Jr. Balrog", "Ghost Stump", "Snail"], 1],
|
["Which monster is not at Victoria Island and Sleepywood?", ["Evil Eye", "Sentinel", "Jr. Balrog", "Ghost Stump", "Snail"], 1],
|
||||||
["El Nath doesn't have which following monsters?", ["Dark Yeti", "Dark Ligator", "Yeti & Pepe", "Bain", "Coolie Zombie"], 1],
|
["El Nath doesn't have which following monsters?", ["Dark Yeti", "Dark Ligator", "Yeti & Pepe", "Bain", "Coolie Zombie"], 1],
|
||||||
["Which of following monsters can fly?", ["Malady", "Ligator", "Cold Eye", "Meerkat", "Alishar"], 0],
|
["Which of following monsters can fly?", ["Malady", "Ligator", "Cold Eye", "Meerkat", "Alishar"], 0],
|
||||||
@@ -80,6 +80,8 @@ var question;
|
|||||||
var questionPool;
|
var questionPool;
|
||||||
var questionPoolCursor;
|
var questionPoolCursor;
|
||||||
|
|
||||||
|
var questionAnswer;
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
status = -1;
|
status = -1;
|
||||||
action(1, 0, 0);
|
action(1, 0, 0);
|
||||||
@@ -121,7 +123,10 @@ function action(mode, type, selection) {
|
|||||||
question = fetchNextQuestion();
|
question = fetchNextQuestion();
|
||||||
var questionHead = generateQuestionHeading();
|
var questionHead = generateQuestionHeading();
|
||||||
var questionEntry = questionTree[question][0];
|
var questionEntry = questionTree[question][0];
|
||||||
var questionOptions = generateSelectionMenu(questionTree[question][1]);
|
|
||||||
|
var questionData = generateSelectionMenu(questionTree[question][1], questionTree[question][2]);
|
||||||
|
var questionOptions = questionData[0];
|
||||||
|
questionAnswer = questionData[1];
|
||||||
|
|
||||||
cm.sendSimple(questionHead + questionEntry + "\r\n\r\n#b" + questionOptions + "#k");
|
cm.sendSimple(questionHead + questionEntry + "\r\n\r\n#b" + questionOptions + "#k");
|
||||||
} else if(status >= 2 && status <= 5) {
|
} else if(status >= 2 && status <= 5) {
|
||||||
@@ -134,7 +139,10 @@ function action(mode, type, selection) {
|
|||||||
question = fetchNextQuestion();
|
question = fetchNextQuestion();
|
||||||
var questionHead = generateQuestionHeading();
|
var questionHead = generateQuestionHeading();
|
||||||
var questionEntry = questionTree[question][0];
|
var questionEntry = questionTree[question][0];
|
||||||
var questionOptions = generateSelectionMenu(questionTree[question][1]);
|
|
||||||
|
var questionData = generateSelectionMenu(questionTree[question][1], questionTree[question][2]);
|
||||||
|
var questionOptions = questionData[0];
|
||||||
|
questionAnswer = questionData[1];
|
||||||
|
|
||||||
cm.sendSimple(questionHead + questionEntry + "\r\n\r\n#b" + questionOptions + "#k");
|
cm.sendSimple(questionHead + questionEntry + "\r\n\r\n#b" + questionOptions + "#k");
|
||||||
} else if(status == 6) {
|
} else if(status == 6) {
|
||||||
@@ -155,7 +163,7 @@ function action(mode, type, selection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function evaluateAnswer(selection) {
|
function evaluateAnswer(selection) {
|
||||||
return selection == questionTree[question][2];
|
return selection == questionAnswer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateQuestionHeading() {
|
function generateQuestionHeading() {
|
||||||
@@ -189,10 +197,36 @@ function fetchNextQuestion() {
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateSelectionMenu(array) {
|
function shuffle(array) {
|
||||||
|
var currentIndex = array.length, temporaryValue, randomIndex;
|
||||||
|
|
||||||
|
// While there remain elements to shuffle...
|
||||||
|
while (0 !== currentIndex) {
|
||||||
|
|
||||||
|
// Pick a remaining element...
|
||||||
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
|
currentIndex -= 1;
|
||||||
|
|
||||||
|
// And swap it with the current element.
|
||||||
|
temporaryValue = array[currentIndex];
|
||||||
|
array[currentIndex] = array[randomIndex];
|
||||||
|
array[randomIndex] = temporaryValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateSelectionMenu(array, answer) {
|
||||||
|
var answerStr = array[answer], answerPos = -1;
|
||||||
|
|
||||||
|
shuffle(array);
|
||||||
|
|
||||||
var menu = "";
|
var menu = "";
|
||||||
for (var i = 0; i < array.length; i++) {
|
for (var i = 0; i < array.length; i++) {
|
||||||
menu += "#L" + i + "#" + array[i] + "#l\r\n";
|
menu += "#L" + i + "#" + array[i] + "#l\r\n";
|
||||||
|
if (answerStr == array[i]) {
|
||||||
|
answerPos = i;
|
||||||
}
|
}
|
||||||
return menu;
|
}
|
||||||
|
return [menu, answerPos];
|
||||||
}
|
}
|
||||||
@@ -107,14 +107,14 @@ function action(mode, type, selection) {
|
|||||||
} else {
|
} else {
|
||||||
if(cm.haveItem(4031061) && cm.haveItem(4031062)) {
|
if(cm.haveItem(4031061) && cm.haveItem(4031062)) {
|
||||||
if(!cm.haveItem(4000082, 30)) {
|
if(!cm.haveItem(4000082, 30)) {
|
||||||
cm.sendOk("You have completed the trials, however there's still the need of #b30 #t4000082##k to forge the #t4001017#.");
|
cm.sendOk("You have completed the trials, however there's still the need of #b30 #t4000082##k to forge 5 #t4001017#.");
|
||||||
} else {
|
} else {
|
||||||
cm.completeQuest(100201);
|
cm.completeQuest(100201);
|
||||||
cm.gainItem(4031061, -1);
|
cm.gainItem(4031061, -1);
|
||||||
cm.gainItem(4031062, -1);
|
cm.gainItem(4031062, -1);
|
||||||
cm.gainItem(4000082, -30);
|
cm.gainItem(4000082, -30);
|
||||||
|
|
||||||
cm.gainItem(4001017, 1);
|
cm.gainItem(4001017, 5);
|
||||||
cm.sendNext("You #rhave completed the trials#k, from now on having my approval to challenge Zakum.");
|
cm.sendNext("You #rhave completed the trials#k, from now on having my approval to challenge Zakum.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,19 +82,22 @@ function writeFeatureTab_PlayerSocialNetwork() {
|
|||||||
addFeature("Automated support for Player NPCs and Hall of Fame.");
|
addFeature("Automated support for Player NPCs and Hall of Fame.");
|
||||||
addFeature("Engagement & Wedding system.");
|
addFeature("Engagement & Wedding system.");
|
||||||
addFeature("Equipments displays to everyone it's level & EXP info.");
|
addFeature("Equipments displays to everyone it's level & EXP info.");
|
||||||
|
addFeature("Further improved the existent minigame mechanics.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeFeatureTab_CashItems() {
|
function writeFeatureTab_CashItems() {
|
||||||
addFeature("EXP/DROP/Cosmetic Coupons.");
|
addFeature("EXP/DROP/Cosmetic Coupons.");
|
||||||
addFeature("EXP/DROP Coupon as buff effect during active time.");
|
addFeature("EXP/DROP Coupon as buff effect during active time.");
|
||||||
addFeature("Great deal of cash items functional.");
|
addFeature("Great deal of cash items functional.");
|
||||||
|
addFeature("Code coupons functional, with multi-items support.");
|
||||||
|
addFeature("Merged unique ids for pets, rings and cash items.");
|
||||||
addFeature("MapleTV mechanics stabilized and split by world.");
|
addFeature("MapleTV mechanics stabilized and split by world.");
|
||||||
addFeature("GMS-esque omok/match card drop chances.");
|
addFeature("GMS-esque omok/match card drop chances.");
|
||||||
addFeature("New town scroll: antibanish. Counters boss banishes.");
|
addFeature("New town scroll: antibanish. Counters boss banishes.");
|
||||||
addFeature("Inventory system checks for free slot & stack space.");
|
addFeature("Inventory system checks for free slot & stack space.");
|
||||||
addFeature("Storage with 'Arrange Items' feature functional.");
|
addFeature("Storage with 'Arrange Items' feature functional.");
|
||||||
addFeature("Close-quarters evaluation mode for items.");
|
addFeature("Close-quarters evaluation mode for items.");
|
||||||
addFeature("Further improved Karma scissors.");
|
addFeature("Reviewed Karma scissors & Untradeable items.");
|
||||||
addFeature("Scroll for Spikes on Shoes.");
|
addFeature("Scroll for Spikes on Shoes.");
|
||||||
addFeature("Scroll for Cold Protection.");
|
addFeature("Scroll for Cold Protection.");
|
||||||
addFeature("Vega's spell.");
|
addFeature("Vega's spell.");
|
||||||
@@ -133,6 +136,8 @@ function writeFeatureTab_MonstersMapsReactors() {
|
|||||||
addFeature("Updated scripted portals, now with proper portal SFX.");
|
addFeature("Updated scripted portals, now with proper portal SFX.");
|
||||||
addFeature("Reviewed Masteria, W. Tour, N. Desert and Neo City.");
|
addFeature("Reviewed Masteria, W. Tour, N. Desert and Neo City.");
|
||||||
addFeature("Added world maps for M. Castle, W. Tour & Ellin areas.");
|
addFeature("Added world maps for M. Castle, W. Tour & Ellin areas.");
|
||||||
|
addFeature("Added W. Tour & Masteria continents in the world map.");
|
||||||
|
addFeature("Reviewed several issues with W. Map tooltips & links.");
|
||||||
addFeature("Giant Cake boss drops s. bags and Maple items.");
|
addFeature("Giant Cake boss drops s. bags and Maple items.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,6 +202,7 @@ function writeFeatureTab_Commands() {
|
|||||||
addFeature("Rank command highlighting users by world or overall.");
|
addFeature("Rank command highlighting users by world or overall.");
|
||||||
addFeature("Server commands layered by GM levels.");
|
addFeature("Server commands layered by GM levels.");
|
||||||
addFeature("Revamped command files layout - thanks Arthur L!");
|
addFeature("Revamped command files layout - thanks Arthur L!");
|
||||||
|
addFeature("Improved 'Search' performance & added map search.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeFeatureTab_CustomNPCs() {
|
function writeFeatureTab_CustomNPCs() {
|
||||||
@@ -276,7 +282,7 @@ function action(mode, type, selection) {
|
|||||||
status--;
|
status--;
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
var sendStr = "HeavenMS was developed on the timespan of 3 years, based on where Solaxia left. On the meantime many nice features emerged, development aimed to get back the old GMS experience. Now many of these so-long missing features are gracefully presented to you in the shape of this server. Long live MapleStory!!\r\n\r\nThese are the features from #bHeavenMS#k:\r\n\r\n";
|
var sendStr = "HeavenMS was developed on the timespan of 3 years, based on where Solaxia left. I'm glad to say the development itself had continuously been agraciated by dozens of contributors and cheerers (truly thanks for the trusting vow, guys & gals!).\r\n\r\nTalking about results: many nice features emerged, development aimed to get back the old GMS experience. Now many of these so-long missing features are gracefully presented to you in the shape of this server. Long live MapleStory!!\r\n\r\nThese are the features from #bHeavenMS#k:\r\n\r\n";
|
||||||
for(var i = 0; i < tabs.length; i++) {
|
for(var i = 0; i < tabs.length; i++) {
|
||||||
sendStr += "#L" + i + "##b" + tabs[i] + "#k#l\r\n";
|
sendStr += "#L" + i + "##b" + tabs[i] + "#k#l\r\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ function writeServerStaff_HeavenMS() {
|
|||||||
addPerson("Ronan", "Developer");
|
addPerson("Ronan", "Developer");
|
||||||
addPerson("Vcoc", "Freelance Developer");
|
addPerson("Vcoc", "Freelance Developer");
|
||||||
addPerson("Thora", "Contributor");
|
addPerson("Thora", "Contributor");
|
||||||
|
addPerson("GabrielSin", "Contributor");
|
||||||
|
|
||||||
setHistory(2015, 2018);
|
setHistory(2015, 2018);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-27
@@ -16,7 +16,6 @@ CREATE TABLE IF NOT EXISTS `accounts` (
|
|||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
`name` varchar(13) NOT NULL DEFAULT '',
|
`name` varchar(13) NOT NULL DEFAULT '',
|
||||||
`password` varchar(128) NOT NULL DEFAULT '',
|
`password` varchar(128) NOT NULL DEFAULT '',
|
||||||
`salt` varchar(128) DEFAULT NULL,
|
|
||||||
`pin` varchar(10) DEFAULT NULL,
|
`pin` varchar(10) DEFAULT NULL,
|
||||||
`pic` varchar(26) DEFAULT NULL,
|
`pic` varchar(26) DEFAULT NULL,
|
||||||
`loggedin` tinyint(4) NOT NULL DEFAULT '0',
|
`loggedin` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
@@ -4517,7 +4516,7 @@ INSERT IGNORE INTO `temp_data` (`id`, `dropperid`, `itemid`, `minimum_quantity`,
|
|||||||
(4298, 5130107, 4130006, 1, 1, 0, 6000),
|
(4298, 5130107, 4130006, 1, 1, 0, 6000),
|
||||||
(4299, 5130107, 4130011, 1, 1, 0, 6000),
|
(4299, 5130107, 4130011, 1, 1, 0, 6000),
|
||||||
(4300, 5130108, 4000069, 1, 1, 0, 600000),
|
(4300, 5130108, 4000069, 1, 1, 0, 600000),
|
||||||
(4301, 5130108, 4000082, 1, 1, 0, 40000),
|
(4301, 5130108, 4000082, 1, 1, 0, 20000),
|
||||||
(4302, 5130108, 2000003, 1, 1, 0, 20000),
|
(4302, 5130108, 2000003, 1, 1, 0, 20000),
|
||||||
(4303, 5130108, 2000004, 1, 1, 0, 20000),
|
(4303, 5130108, 2000004, 1, 1, 0, 20000),
|
||||||
(4304, 5130108, 2000002, 1, 1, 0, 20000),
|
(4304, 5130108, 2000002, 1, 1, 0, 20000),
|
||||||
@@ -12926,15 +12925,6 @@ CREATE TABLE IF NOT EXISTS `hiredmerchant` (
|
|||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `htsquads` (
|
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
|
||||||
`channel` int(10) unsigned NOT NULL,
|
|
||||||
`leaderid` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`status` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`members` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `hwidaccounts` (
|
CREATE TABLE IF NOT EXISTS `hwidaccounts` (
|
||||||
`accountid` int(11) NOT NULL DEFAULT '0',
|
`accountid` int(11) NOT NULL DEFAULT '0',
|
||||||
`hwid` varchar(40) NOT NULL DEFAULT '',
|
`hwid` varchar(40) NOT NULL DEFAULT '',
|
||||||
@@ -16393,13 +16383,21 @@ CREATE TABLE IF NOT EXISTS `notes` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `nxcode` (
|
CREATE TABLE IF NOT EXISTS `nxcode` (
|
||||||
`code` varchar(15) NOT NULL,
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
`valid` int(11) NOT NULL DEFAULT '1',
|
`code` varchar(17) NOT NULL UNIQUE,
|
||||||
`user` varchar(13) DEFAULT NULL,
|
`retriever` varchar(13) DEFAULT NULL,
|
||||||
`type` int(11) NOT NULL DEFAULT '0',
|
`expiration` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||||
`item` int(11) NOT NULL DEFAULT '10000',
|
PRIMARY KEY (`id`)
|
||||||
PRIMARY KEY (`code`)
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `nxcode_items` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`codeid` int(11) NOT NULL,
|
||||||
|
`type` int(11) NOT NULL DEFAULT '5',
|
||||||
|
`item` int(11) NOT NULL DEFAULT '4000000',
|
||||||
|
`quantity` int(11) NOT NULL DEFAULT '1',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `nxcoupons` (
|
CREATE TABLE IF NOT EXISTS `nxcoupons` (
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
@@ -21414,15 +21412,6 @@ CREATE TABLE IF NOT EXISTS `wishlists` (
|
|||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `zaksquads` (
|
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
|
||||||
`channel` int(10) unsigned NOT NULL,
|
|
||||||
`leaderid` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`status` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
`members` int(10) unsigned NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
|
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE `dueyitems`
|
ALTER TABLE `dueyitems`
|
||||||
ADD CONSTRAINT `dueyitems_ibfk_1` FOREIGN KEY (`PackageId`) REFERENCES `dueypackages` (`PackageId`) ON DELETE CASCADE;
|
ADD CONSTRAINT `dueyitems_ibfk_1` FOREIGN KEY (`PackageId`) REFERENCES `dueypackages` (`PackageId`) ON DELETE CASCADE;
|
||||||
|
|||||||
+51
-51
@@ -412,9 +412,9 @@ USE `heavenms`;
|
|||||||
(1210102, 4030001, 1, 1, 0, 10000),
|
(1210102, 4030001, 1, 1, 0, 10000),
|
||||||
(9300229, 4030001, 1, 1, 0, 10000),
|
(9300229, 4030001, 1, 1, 0, 10000),
|
||||||
(9500102, 4030001, 1, 1, 0, 10000),
|
(9500102, 4030001, 1, 1, 0, 10000),
|
||||||
(1210102, 4001345, 1, 1, 0, 7000),
|
(1210102, 4001345, 1, 1, 0, 70000),
|
||||||
(9300229, 4001345, 1, 1, 0, 7000),
|
(9300229, 4001345, 1, 1, 0, 70000),
|
||||||
(9500102, 4001345, 1, 1, 0, 7000),
|
(9500102, 4001345, 1, 1, 0, 70000),
|
||||||
(1210102, 2000000, 1, 1, 0, 40000),
|
(1210102, 2000000, 1, 1, 0, 40000),
|
||||||
(9300229, 2000000, 1, 1, 0, 40000),
|
(9300229, 2000000, 1, 1, 0, 40000),
|
||||||
(9500102, 2000000, 1, 1, 0, 40000),
|
(9500102, 2000000, 1, 1, 0, 40000),
|
||||||
@@ -508,18 +508,18 @@ USE `heavenms`;
|
|||||||
(1210101, 4000021, 1, 1, 0, 200000),
|
(1210101, 4000021, 1, 1, 0, 200000),
|
||||||
(9300059, 4000021, 1, 1, 0, 200000),
|
(9300059, 4000021, 1, 1, 0, 200000),
|
||||||
(9400242, 4000021, 1, 1, 0, 200000),
|
(9400242, 4000021, 1, 1, 0, 200000),
|
||||||
(1210101, 4003004, 1, 1, 0, 7000),
|
(1210101, 4003004, 1, 1, 0, 70000),
|
||||||
(9300059, 4003004, 1, 1, 0, 7000),
|
(9300059, 4003004, 1, 1, 0, 70000),
|
||||||
(9400242, 4003004, 1, 1, 0, 7000),
|
(9400242, 4003004, 1, 1, 0, 70000),
|
||||||
(1210101, 4030012, 1, 1, 0, 125000),
|
(1210101, 4030012, 1, 1, 0, 125000),
|
||||||
(9300059, 4030012, 1, 1, 0, 125000),
|
(9300059, 4030012, 1, 1, 0, 125000),
|
||||||
(9400242, 4030012, 1, 1, 0, 125000),
|
(9400242, 4030012, 1, 1, 0, 125000),
|
||||||
(1210101, 4001343, 1, 1, 0, 7000),
|
(1210101, 4001343, 1, 1, 0, 70000),
|
||||||
(9300059, 4001343, 1, 1, 0, 7000),
|
(9300059, 4001343, 1, 1, 0, 70000),
|
||||||
(9400242, 4001343, 1, 1, 0, 7000),
|
(9400242, 4001343, 1, 1, 0, 70000),
|
||||||
(1210101, 4001342, 1, 1, 0, 7000),
|
(1210101, 4001342, 1, 1, 0, 70000),
|
||||||
(9300059, 4001342, 1, 1, 0, 7000),
|
(9300059, 4001342, 1, 1, 0, 70000),
|
||||||
(9400242, 4001342, 1, 1, 0, 7000),
|
(9400242, 4001342, 1, 1, 0, 70000),
|
||||||
(1210101, 2000000, 1, 1, 0, 40000),
|
(1210101, 2000000, 1, 1, 0, 40000),
|
||||||
(9300059, 2000000, 1, 1, 0, 40000),
|
(9300059, 2000000, 1, 1, 0, 40000),
|
||||||
(9400242, 2000000, 1, 1, 0, 40000),
|
(9400242, 2000000, 1, 1, 0, 40000),
|
||||||
@@ -566,9 +566,9 @@ USE `heavenms`;
|
|||||||
(9300059, 1072285, 1, 1, 0, 700),
|
(9300059, 1072285, 1, 1, 0, 700),
|
||||||
(9400242, 1072285, 1, 1, 0, 700),
|
(9400242, 1072285, 1, 1, 0, 700),
|
||||||
(1110101, 4030009, 1, 1, 0, 28000),
|
(1110101, 4030009, 1, 1, 0, 28000),
|
||||||
(1110101, 4001344, 1, 1, 0, 7000),
|
(1110101, 4001344, 1, 1, 0, 70000),
|
||||||
(1110101, 4001356, 1, 1, 0, 7000),
|
(1110101, 4001356, 1, 1, 0, 70000),
|
||||||
(1110101, 4001360, 1, 1, 0, 12000),
|
(1110101, 4001360, 1, 1, 0, 120000),
|
||||||
(1110101, 2000000, 1, 1, 0, 40000),
|
(1110101, 2000000, 1, 1, 0, 40000),
|
||||||
(1110101, 2040802, 1, 1, 0, 750),
|
(1110101, 2040802, 1, 1, 0, 750),
|
||||||
(1110101, 2380008, 1, 1, 0, 0),
|
(1110101, 2380008, 1, 1, 0, 0),
|
||||||
@@ -4654,7 +4654,7 @@ USE `heavenms`;
|
|||||||
(9300186, 1082195, 1, 1, 0, 40000),
|
(9300186, 1082195, 1, 1, 0, 40000),
|
||||||
(9500339, 1082195, 1, 1, 0, 40000),
|
(9500339, 1082195, 1, 1, 0, 40000),
|
||||||
(9303003, 1082195, 1, 1, 0, 700),
|
(9303003, 1082195, 1, 1, 0, 700),
|
||||||
(3300008, 4001318, 1, 1, 0, 7000),
|
(3300008, 4001318, 1, 1, 0, 600000),
|
||||||
(3300008, 2388070, 1, 4, 0, 20000),
|
(3300008, 2388070, 1, 4, 0, 20000),
|
||||||
(3300008, 2000002, 1, 4, 0, 40000),
|
(3300008, 2000002, 1, 4, 0, 40000),
|
||||||
(3300008, 2000003, 1, 4, 0, 40000),
|
(3300008, 2000003, 1, 4, 0, 40000),
|
||||||
@@ -16180,8 +16180,8 @@ USE `heavenms`;
|
|||||||
(9420513, 1060106, 1, 1, 0, 40000),
|
(9420513, 1060106, 1, 1, 0, 40000),
|
||||||
(9420513, 1072173, 1, 1, 0, 40000),
|
(9420513, 1072173, 1, 1, 0, 40000),
|
||||||
(9420513, 1332026, 1, 1, 0, 40000),
|
(9420513, 1332026, 1, 1, 0, 40000),
|
||||||
(9400549, 4031903, 1, 1, 0, 7000),
|
(9400549, 4031903, 1, 1, 0, 100000),
|
||||||
(9400571, 4031903, 1, 1, 0, 7000),
|
(9400571, 4031903, 1, 1, 0, 100000),
|
||||||
(9400549, 2020014, 1, 4, 0, 3000),
|
(9400549, 2020014, 1, 4, 0, 3000),
|
||||||
(9400571, 2020014, 1, 4, 0, 3000),
|
(9400571, 2020014, 1, 4, 0, 3000),
|
||||||
(9400549, 2002025, 1, 4, 0, 10000),
|
(9400549, 2002025, 1, 4, 0, 10000),
|
||||||
@@ -20007,29 +20007,29 @@ USE `heavenms`;
|
|||||||
(9300154, 4031782, 1, 1, 0, 400000),
|
(9300154, 4031782, 1, 1, 0, 400000),
|
||||||
(9300154, 4031783, 1, 1, 0, 400000),
|
(9300154, 4031783, 1, 1, 0, 400000),
|
||||||
(9300154, 4031784, 1, 1, 0, 400000),
|
(9300154, 4031784, 1, 1, 0, 400000),
|
||||||
(1110100, 4032317, 1, 1, 21717, 20000),
|
(1110100, 4032317, 1, 1, 21717, 40000),
|
||||||
(1110130, 4032317, 1, 1, 21717, 20000),
|
(1110130, 4032317, 1, 1, 21717, 40000),
|
||||||
(1110100, 4032318, 1, 1, 21718, 20000),
|
(1110100, 4032318, 1, 1, 21718, 40000),
|
||||||
(1110130, 4032318, 1, 1, 21718, 20000),
|
(1110130, 4032318, 1, 1, 21718, 40000),
|
||||||
(9400204, 4130020, 1, 1, 0, 3000),
|
(9400204, 4130020, 1, 1, 0, 3000),
|
||||||
(9400614, 4001341, 1, 1, 28172, 15000),
|
(9400614, 4001341, 1, 1, 28172, 30000),
|
||||||
(9400615, 4001341, 1, 1, 28172, 15000),
|
(9400615, 4001341, 1, 1, 28172, 30000),
|
||||||
(9400616, 4001341, 1, 1, 28172, 15000),
|
(9400616, 4001341, 1, 1, 28172, 30000),
|
||||||
(1110101, 4001347, 1, 1, 28229, 80000),
|
(1110101, 4001347, 1, 1, 28229, 160000),
|
||||||
(1110100, 4001348, 1, 1, 28231, 400000),
|
(1110100, 4001348, 1, 1, 28231, 800000),
|
||||||
(1120100, 4001349, 1, 1, 28235, 100000),
|
(1120100, 4001349, 1, 1, 28235, 200000),
|
||||||
(1210101, 4001350, 1, 1, 28235, 100000),
|
(1210101, 4001350, 1, 1, 28235, 200000),
|
||||||
(2220100, 4001351, 1, 1, 28237, 100000),
|
(2220100, 4001351, 1, 1, 28237, 200000),
|
||||||
(9400614, 4001352, 1, 1, 28205, 40000),
|
(9400614, 4001352, 1, 1, 28205, 80000),
|
||||||
(9400615, 4001352, 1, 1, 28205, 40000),
|
(9400615, 4001352, 1, 1, 28205, 80000),
|
||||||
(9400616, 4001352, 1, 1, 28205, 40000),
|
(9400616, 4001352, 1, 1, 28205, 80000),
|
||||||
(9400617, 4001352, 1, 1, 28205, 40000),
|
(9400617, 4001352, 1, 1, 28205, 80000),
|
||||||
(9400617, 4001362, 1, 1, 28252, 40000),
|
(9400617, 4001362, 1, 1, 28252, 80000),
|
||||||
(9400655, 4001362, 1, 1, 28252, 40000),
|
(9400655, 4001362, 1, 1, 28252, 80000),
|
||||||
(9400656, 4001362, 1, 1, 28252, 40000),
|
(9400656, 4001362, 1, 1, 28252, 80000),
|
||||||
(9400617, 4001363, 1, 1, 28252, 40000),
|
(9400617, 4001363, 1, 1, 28252, 80000),
|
||||||
(9400655, 4001363, 1, 1, 28252, 40000),
|
(9400655, 4001363, 1, 1, 28252, 80000),
|
||||||
(9400656, 4001363, 1, 1, 28252, 40000),
|
(9400656, 4001363, 1, 1, 28252, 80000),
|
||||||
(9400609, 2000002, 1, 1, 0, 40000),
|
(9400609, 2000002, 1, 1, 0, 40000),
|
||||||
(9400609, 2000003, 1, 1, 0, 40000),
|
(9400609, 2000003, 1, 1, 0, 40000),
|
||||||
(9400609, 2000004, 1, 1, 0, 10000),
|
(9400609, 2000004, 1, 1, 0, 10000),
|
||||||
@@ -20077,17 +20077,17 @@ USE `heavenms`;
|
|||||||
(9400613, 1082258, 1, 1, 0, 5000),
|
(9400613, 1082258, 1, 1, 0, 5000),
|
||||||
(9400613, 1072421, 1, 1, 0, 5000),
|
(9400613, 1072421, 1, 1, 0, 5000),
|
||||||
(4110302, 2383007, 1, 1, 0, 8000),
|
(4110302, 2383007, 1, 1, 0, 8000),
|
||||||
(130100, 4032374, 1, 1, 2405, 40000),
|
(130100, 4032374, 1, 1, 2405, 80000),
|
||||||
(1110101, 4032374, 1, 1, 2405, 40000),
|
(1110101, 4032374, 1, 1, 2405, 80000),
|
||||||
(210100, 4032376, 1, 1, 2406, 40000),
|
(210100, 4032376, 1, 1, 2406, 80000),
|
||||||
(1110101, 4032376, 1, 1, 2406, 40000),
|
(1110101, 4032376, 1, 1, 2406, 80000),
|
||||||
(210100, 4032377, 1, 1, 2407, 40000),
|
(210100, 4032377, 1, 1, 2407, 80000),
|
||||||
(1210101, 4032377, 1, 1, 2407, 40000),
|
(1210101, 4032377, 1, 1, 2407, 80000),
|
||||||
(130100, 4032378, 1, 1, 2408, 40000),
|
(130100, 4032378, 1, 1, 2408, 80000),
|
||||||
(1120100, 4032378, 1, 1, 2408, 40000),
|
(1120100, 4032378, 1, 1, 2408, 80000),
|
||||||
(1110100, 4032379, 1, 1, 2409, 40000),
|
(1110100, 4032379, 1, 1, 2409, 80000),
|
||||||
(1210100, 4032379, 1, 1, 2409, 40000),
|
(1210100, 4032379, 1, 1, 2409, 80000),
|
||||||
(2130100, 4001344, 1, 1, 0, 7000),
|
(2130100, 4001344, 1, 1, 0, 70000),
|
||||||
(7220002, 4031789, 1, 1, 3844, 999999),
|
(7220002, 4031789, 1, 1, 3844, 999999),
|
||||||
(8830007, 1302112, 1, 1, 0, 4000),
|
(8830007, 1302112, 1, 1, 0, 4000),
|
||||||
(8830007, 1302113, 1, 1, 0, 4000),
|
(8830007, 1302113, 1, 1, 0, 4000),
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
|||||||
protected int hpMpApUsed, remainingAp;
|
protected int hpMpApUsed, remainingAp;
|
||||||
protected int[] remainingSp = new int[10];
|
protected int[] remainingSp = new int[10];
|
||||||
protected transient int clientmaxhp, clientmaxmp, localmaxhp = 50, localmaxmp = 5;
|
protected transient int clientmaxhp, clientmaxmp, localmaxhp = 50, localmaxmp = 5;
|
||||||
|
protected float transienthp = Float.NEGATIVE_INFINITY, transientmp = Float.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
private AbstractCharacterListener listener = null;
|
private AbstractCharacterListener listener = null;
|
||||||
protected Map<MapleStat, Integer> statUpdates = new HashMap<>();
|
protected Map<MapleStat, Integer> statUpdates = new HashMap<>();
|
||||||
@@ -222,6 +223,8 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
|||||||
} else if (thp > localmaxhp) {
|
} else if (thp > localmaxhp) {
|
||||||
thp = localmaxhp;
|
thp = localmaxhp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.hp != thp) this.transienthp = Float.NEGATIVE_INFINITY;
|
||||||
this.hp = thp;
|
this.hp = thp;
|
||||||
|
|
||||||
dispatchHpChanged(oldHp);
|
dispatchHpChanged(oldHp);
|
||||||
@@ -234,6 +237,8 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
|||||||
} else if (tmp > localmaxmp) {
|
} else if (tmp > localmaxmp) {
|
||||||
tmp = localmaxmp;
|
tmp = localmaxmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.mp != tmp) this.transientmp = Float.NEGATIVE_INFINITY;
|
||||||
this.mp = tmp;
|
this.mp = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,11 +251,13 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void setMaxHp(int hp_) {
|
protected void setMaxHp(int hp_) {
|
||||||
|
if (this.maxhp < hp_) this.transienthp = Float.NEGATIVE_INFINITY;
|
||||||
this.maxhp = hp_;
|
this.maxhp = hp_;
|
||||||
this.clientmaxhp = Math.min(30000, hp_);
|
this.clientmaxhp = Math.min(30000, hp_);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setMaxMp(int mp_) {
|
protected void setMaxMp(int mp_) {
|
||||||
|
if (this.maxmp < mp_) this.transientmp = Float.NEGATIVE_INFINITY;
|
||||||
this.maxmp = mp_;
|
this.maxmp = mp_;
|
||||||
this.clientmaxmp = Math.min(30000, mp_);
|
this.clientmaxmp = Math.min(30000, mp_);
|
||||||
}
|
}
|
||||||
|
|||||||
+201
-49
@@ -118,6 +118,7 @@ import client.inventory.MaplePet;
|
|||||||
import client.inventory.MapleWeaponType;
|
import client.inventory.MapleWeaponType;
|
||||||
import client.inventory.ModifyInventory;
|
import client.inventory.ModifyInventory;
|
||||||
import client.inventory.PetDataFactory;
|
import client.inventory.PetDataFactory;
|
||||||
|
import client.inventory.manipulator.MapleCashidGenerator;
|
||||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||||
import client.newyear.NewYearCardRecord;
|
import client.newyear.NewYearCardRecord;
|
||||||
import constants.ExpTable;
|
import constants.ExpTable;
|
||||||
@@ -1341,12 +1342,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean buffMapProtection() {
|
private boolean buffMapProtection() {
|
||||||
effLock.lock();
|
|
||||||
chrLock.lock();
|
|
||||||
|
|
||||||
int thisMapid = mapid;
|
int thisMapid = mapid;
|
||||||
int returnMapid = client.getChannelServer().getMapFactory().getMap(thisMapid).getReturnMapId();
|
int returnMapid = client.getChannelServer().getMapFactory().getMap(thisMapid).getReturnMapId();
|
||||||
|
|
||||||
|
effLock.lock();
|
||||||
|
chrLock.lock();
|
||||||
try {
|
try {
|
||||||
for(Entry<MapleBuffStat, MapleBuffStatValueHolder> mbs : effects.entrySet()) {
|
for(Entry<MapleBuffStat, MapleBuffStatValueHolder> mbs : effects.entrySet()) {
|
||||||
if(mbs.getKey() == MapleBuffStat.MAP_PROTECTION) {
|
if(mbs.getKey() == MapleBuffStat.MAP_PROTECTION) {
|
||||||
@@ -1903,7 +1903,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
Skill battleship = SkillFactory.getSkill(Corsair.BATTLE_SHIP);
|
Skill battleship = SkillFactory.getSkill(Corsair.BATTLE_SHIP);
|
||||||
int cooldown = battleship.getEffect(getSkillLevel(battleship)).getCooldown();
|
int cooldown = battleship.getEffect(getSkillLevel(battleship)).getCooldown();
|
||||||
announce(MaplePacketCreator.skillCooldown(Corsair.BATTLE_SHIP, cooldown));
|
announce(MaplePacketCreator.skillCooldown(Corsair.BATTLE_SHIP, cooldown));
|
||||||
addCooldown(Corsair.BATTLE_SHIP, System.currentTimeMillis(), (long)(cooldown * 1000));
|
addCooldown(Corsair.BATTLE_SHIP, Server.getInstance().getCurrentTime(), (long)(cooldown * 1000));
|
||||||
removeCooldown(5221999);
|
removeCooldown(5221999);
|
||||||
cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
|
cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
|
||||||
} else {
|
} else {
|
||||||
@@ -2080,6 +2080,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
ps3.setInt(1, ringid);
|
ps3.setInt(1, ringid);
|
||||||
ps3.executeUpdate();
|
ps3.executeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapleCashidGenerator.freeCashId(ringid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2090,11 +2092,13 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
ps2.executeUpdate();
|
ps2.executeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rs.getInt("petid") > -1) {
|
int petid = rs.getInt("petid");
|
||||||
|
if(petid > -1) {
|
||||||
try (PreparedStatement ps2 = con.prepareStatement("DELETE FROM pets WHERE petid = ?")) {
|
try (PreparedStatement ps2 = con.prepareStatement("DELETE FROM pets WHERE petid = ?")) {
|
||||||
ps2.setInt(1, rs.getInt("petid"));
|
ps2.setInt(1, petid);
|
||||||
ps2.executeUpdate();
|
ps2.executeUpdate();
|
||||||
}
|
}
|
||||||
|
MapleCashidGenerator.freeCashId(petid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2453,6 +2457,10 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
chrLock.unlock();
|
chrLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (disease == MapleDisease.SEDUCE && chair.get() != 0) {
|
||||||
|
sitChair(0);
|
||||||
|
}
|
||||||
|
|
||||||
final List<Pair<MapleDisease, Integer>> debuff = Collections.singletonList(new Pair<>(disease, Integer.valueOf(skill.getX())));
|
final List<Pair<MapleDisease, Integer>> debuff = Collections.singletonList(new Pair<>(disease, Integer.valueOf(skill.getX())));
|
||||||
client.announce(MaplePacketCreator.giveDebuff(debuff, skill));
|
client.announce(MaplePacketCreator.giveDebuff(debuff, skill));
|
||||||
|
|
||||||
@@ -2550,7 +2558,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
public void run() {
|
public void run() {
|
||||||
doHurtHp();
|
doHurtHp();
|
||||||
}
|
}
|
||||||
}, 10000, 10000 - lastHpTask);
|
}, ServerConstants.MAP_DAMAGE_OVERTIME_INTERVAL, ServerConstants.MAP_DAMAGE_OVERTIME_INTERVAL - lastHpTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetHpDecreaseTask() {
|
public void resetHpDecreaseTask() {
|
||||||
@@ -2559,7 +2567,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long lastHpTask = Server.getInstance().getCurrentTime() - lastHpDec;
|
long lastHpTask = Server.getInstance().getCurrentTime() - lastHpDec;
|
||||||
startHpDecreaseTask((lastHpTask > 10000) ? 10000 : lastHpTask);
|
startHpDecreaseTask((lastHpTask > ServerConstants.MAP_DAMAGE_OVERTIME_INTERVAL) ? ServerConstants.MAP_DAMAGE_OVERTIME_INTERVAL : lastHpTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dropMessage(String message) {
|
public void dropMessage(String message) {
|
||||||
@@ -2682,7 +2690,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
effLock.unlock();
|
effLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
long curTime = System.currentTimeMillis();
|
long curTime = Server.getInstance().getCurrentTime();
|
||||||
for(Entry<Integer, MapleCoolDownValueHolder> bel : es) {
|
for(Entry<Integer, MapleCoolDownValueHolder> bel : es) {
|
||||||
MapleCoolDownValueHolder mcdvh = bel.getValue();
|
MapleCoolDownValueHolder mcdvh = bel.getValue();
|
||||||
if(curTime >= mcdvh.startTime + mcdvh.length) {
|
if(curTime >= mcdvh.startTime + mcdvh.length) {
|
||||||
@@ -5247,8 +5255,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
this.battleshipHp = (int) length;
|
this.battleshipHp = (int) length;
|
||||||
addCooldown(skillid, 0, length);
|
addCooldown(skillid, 0, length);
|
||||||
} else {
|
} else {
|
||||||
int time = (int) ((length + starttime) - System.currentTimeMillis());
|
long timeNow = Server.getInstance().getCurrentTime();
|
||||||
addCooldown(skillid, System.currentTimeMillis(), time);
|
int time = (int) ((length + starttime) - timeNow);
|
||||||
|
addCooldown(skillid, timeNow, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5433,9 +5442,43 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
int grade = Math.min(Math.max(level, 30), 120) - 30;
|
int grade = Math.min(Math.max(level, 30), 120) - 30;
|
||||||
|
|
||||||
fee += (grade * ServerConstants.BUYBACK_LEVEL_STACK_FEE);
|
fee += (grade * ServerConstants.BUYBACK_LEVEL_STACK_FEE);
|
||||||
|
if (ServerConstants.USE_BUYBACK_WITH_MESOS) fee *= ServerConstants.BUYBACK_MESO_MULTIPLIER;
|
||||||
|
|
||||||
return (int) Math.floor(fee);
|
return (int) Math.floor(fee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showBuybackInfo() {
|
||||||
|
String s = "#eBUYBACK STATUS#n\r\n\r\nCurrent buyback fee: #b" + getBuybackFee() + " " + (ServerConstants.USE_BUYBACK_WITH_MESOS ? "mesos" : "NX") + "#k\r\n\r\n";
|
||||||
|
|
||||||
|
long timeNow = Server.getInstance().getCurrentTime();
|
||||||
|
boolean avail = true;
|
||||||
|
if (!isAlive()) {
|
||||||
|
long timeLapsed = timeNow - lastDeathtime;
|
||||||
|
long timeRemaining = ServerConstants.BUYBACK_RETURN_MINUTES * 60 * 1000 - (timeLapsed + Math.max(0, getNextBuybackTime() - timeNow));
|
||||||
|
if (timeRemaining < 1) {
|
||||||
|
s += "Buyback #e#rUNAVAILABLE#k#n";
|
||||||
|
avail = false;
|
||||||
|
} else {
|
||||||
|
s += "Buyback countdown: #e#b" + getTimeRemaining(ServerConstants.BUYBACK_RETURN_MINUTES * 60 * 1000 - timeLapsed) + "#k#n";
|
||||||
|
}
|
||||||
|
s += "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeNow < getNextBuybackTime() && avail) {
|
||||||
|
s += "Buyback available in #r" + getTimeRemaining(getNextBuybackTime() - timeNow) + "#k";
|
||||||
|
s += "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showHint(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getTimeRemaining(long timeLeft) {
|
||||||
|
int seconds = (int) Math.floor(timeLeft / 1000) % 60;
|
||||||
|
int minutes = (int) Math.floor(timeLeft / (1000*60)) % 60;
|
||||||
|
|
||||||
|
return (minutes > 0 ? (String.format("%02d", minutes) + " minutes, ") : "") + String.format("%02d", seconds) + " seconds";
|
||||||
|
}
|
||||||
|
|
||||||
public boolean couldBuyback() { // Ronan's buyback system
|
public boolean couldBuyback() { // Ronan's buyback system
|
||||||
long timeNow = Server.getInstance().getCurrentTime();
|
long timeNow = Server.getInstance().getCurrentTime();
|
||||||
|
|
||||||
@@ -5447,16 +5490,12 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
long nextBuybacktime = getNextBuybackTime();
|
long nextBuybacktime = getNextBuybackTime();
|
||||||
if (timeNow < nextBuybacktime) {
|
if (timeNow < nextBuybacktime) {
|
||||||
long timeLeft = nextBuybacktime - timeNow;
|
long timeLeft = nextBuybacktime - timeNow;
|
||||||
int seconds = (int) Math.floor(timeLeft / 1000) % 60;
|
this.dropMessage(5, "Next buyback available in " + getTimeRemaining(timeLeft) + ".");
|
||||||
int minutes = (int) Math.floor(timeLeft / (1000*60)) % 60;
|
|
||||||
|
|
||||||
this.dropMessage(5, "Next buyback available in " + (minutes > 0 ? (String.format("%02d", minutes) + " minutes, ") : "") + String.format("%02d", seconds) + " seconds.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean usingMesos = ServerConstants.USE_BUYBACK_WITH_MESOS;
|
boolean usingMesos = ServerConstants.USE_BUYBACK_WITH_MESOS;
|
||||||
int fee = getBuybackFee();
|
int fee = getBuybackFee();
|
||||||
if (usingMesos) fee *= ServerConstants.BUYBACK_MESO_MULTIPLIER;
|
|
||||||
|
|
||||||
if (!canBuyback(fee, usingMesos)) {
|
if (!canBuyback(fee, usingMesos)) {
|
||||||
this.dropMessage(5, "You don't have " + fee + " " + (usingMesos ? "mesos" : "NX") + " to buyback.");
|
this.dropMessage(5, "You don't have " + fee + " " + (usingMesos ? "mesos" : "NX") + " to buyback.");
|
||||||
@@ -5528,7 +5567,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
public void leaveMap() {
|
public void leaveMap() {
|
||||||
controlled.clear();
|
controlled.clear();
|
||||||
visibleMapObjects.clear();
|
visibleMapObjects.clear();
|
||||||
chair.set(0);
|
setChair(0);
|
||||||
if (hpDecreaseTask != null) {
|
if (hpDecreaseTask != null) {
|
||||||
hpDecreaseTask.cancel(false);
|
hpDecreaseTask.cancel(false);
|
||||||
}
|
}
|
||||||
@@ -5710,7 +5749,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
if (ServerConstants.USE_PERFECT_PITCH && level >= 30) {
|
if (ServerConstants.USE_PERFECT_PITCH && level >= 30) {
|
||||||
//milestones?
|
//milestones?
|
||||||
if (MapleInventoryManipulator.checkSpace(client, 4310000, (short) 1, "")) {
|
if (MapleInventoryManipulator.checkSpace(client, 4310000, (short) 1, "")) {
|
||||||
MapleInventoryManipulator.addById(client, 4310000, (short) 1);
|
MapleInventoryManipulator.addById(client, 4310000, (short) 1, "", -1);
|
||||||
}
|
}
|
||||||
} else if (level == 10) {
|
} else if (level == 10) {
|
||||||
Runnable r = new Runnable() {
|
Runnable r = new Runnable() {
|
||||||
@@ -6452,7 +6491,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
ps = con.prepareStatement("SELECT SkillID,StartTime,length FROM cooldowns WHERE charid = ?");
|
ps = con.prepareStatement("SELECT SkillID,StartTime,length FROM cooldowns WHERE charid = ?");
|
||||||
ps.setInt(1, ret.getId());
|
ps.setInt(1, ret.getId());
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
long curTime = System.currentTimeMillis();
|
long curTime = Server.getInstance().getCurrentTime();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
final int skillid = rs.getInt("SkillID");
|
final int skillid = rs.getInt("SkillID");
|
||||||
final long length = rs.getLong("length"), startTime = rs.getLong("StartTime");
|
final long length = rs.getLong("length"), startTime = rs.getLong("StartTime");
|
||||||
@@ -6534,7 +6573,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
ret.storage = MapleStorage.loadOrCreateFromDB(ret.accountid, ret.world);
|
ret.storage = MapleStorage.loadOrCreateFromDB(ret.accountid, ret.world);
|
||||||
|
|
||||||
int startHp = ret.hp, startMp = ret.mp;
|
int startHp = ret.hp, startMp = ret.mp;
|
||||||
ret.recalcLocalStats();
|
ret.reapplyLocalStats();
|
||||||
ret.changeHpMp(startHp, startMp, true);
|
ret.changeHpMp(startHp, startMp, true);
|
||||||
//ret.resetBattleshipHp();
|
//ret.resetBattleshipHp();
|
||||||
}
|
}
|
||||||
@@ -6651,7 +6690,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
private void playerDead() {
|
private void playerDead() {
|
||||||
cancelAllBuffs(false);
|
cancelAllBuffs(false);
|
||||||
dispelDebuffs();
|
dispelDebuffs();
|
||||||
lastDeathtime = System.currentTimeMillis();
|
lastDeathtime = Server.getInstance().getCurrentTime();
|
||||||
|
|
||||||
EventInstanceManager eim = getEventInstance();
|
EventInstanceManager eim = getEventInstance();
|
||||||
if (eim != null) {
|
if (eim != null) {
|
||||||
@@ -6702,14 +6741,53 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
|
cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getChair() != 0) {
|
unsitChairInternal();
|
||||||
setChair(0);
|
|
||||||
client.announce(MaplePacketCreator.cancelChair(-1));
|
|
||||||
getMap().broadcastMessage(this, MaplePacketCreator.showChair(getId(), 0), false);
|
|
||||||
}
|
|
||||||
client.announce(MaplePacketCreator.enableActions());
|
client.announce(MaplePacketCreator.enableActions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void unsitChairInternal() {
|
||||||
|
if (chair.get() != 0) {
|
||||||
|
setChair(0);
|
||||||
|
if (unregisterChairBuff()) {
|
||||||
|
getMap().broadcastMessage(this, MaplePacketCreator.cancelForeignChairSkillEffect(this.getId()), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMap().broadcastMessage(this, MaplePacketCreator.showChair(this.getId(), 0), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
announce(MaplePacketCreator.cancelChair(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sitChair(int itemId) {
|
||||||
|
if (client.tryacquireClient()) {
|
||||||
|
try {
|
||||||
|
if (itemId >= 1000000) { // sit on item chair
|
||||||
|
if (chair.get() == 0) {
|
||||||
|
setChair(itemId);
|
||||||
|
getMap().broadcastMessage(this, MaplePacketCreator.showChair(this.getId(), itemId), false);
|
||||||
|
}
|
||||||
|
announce(MaplePacketCreator.enableActions());
|
||||||
|
} else if (itemId != 0) { // sit on map chair
|
||||||
|
if (chair.get() == 0) {
|
||||||
|
setChair(itemId);
|
||||||
|
if (registerChairBuff()) {
|
||||||
|
getMap().broadcastMessage(this, MaplePacketCreator.giveForeignChairSkillEffect(this.getId()), false);
|
||||||
|
}
|
||||||
|
announce(MaplePacketCreator.cancelChair(itemId));
|
||||||
|
}
|
||||||
|
} else { // stand up
|
||||||
|
unsitChairInternal();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
client.releaseClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setChair(int chair) {
|
||||||
|
this.chair.set(chair);
|
||||||
|
}
|
||||||
|
|
||||||
public void respawn(int returnMap) {
|
public void respawn(int returnMap) {
|
||||||
respawn(null, returnMap); // unspecified EIM, don't force EIM unregister in this case
|
respawn(null, returnMap); // unspecified EIM, don't force EIM unregister in this case
|
||||||
}
|
}
|
||||||
@@ -6780,15 +6858,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
localwatk += equipwatk;
|
localwatk += equipwatk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Pair<MapleStat, Integer>> recalcLocalStats() {
|
private void reapplyLocalStats() {
|
||||||
effLock.lock();
|
effLock.lock();
|
||||||
|
chrLock.lock();
|
||||||
statWlock.lock();
|
statWlock.lock();
|
||||||
try {
|
try {
|
||||||
List<Pair<MapleStat, Integer>> hpmpupdate = new ArrayList<>(2);
|
|
||||||
|
|
||||||
int oldlocalmaxhp = localmaxhp;
|
|
||||||
int oldlocalmaxmp = localmaxmp;
|
|
||||||
|
|
||||||
localmaxhp = getMaxHp();
|
localmaxhp = getMaxHp();
|
||||||
localmaxmp = getMaxMp();
|
localmaxmp = getMaxMp();
|
||||||
localdex = getDex();
|
localdex = getDex();
|
||||||
@@ -6815,11 +6889,6 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
localmaxhp = Math.min(30000, localmaxhp);
|
localmaxhp = Math.min(30000, localmaxhp);
|
||||||
localmaxmp = Math.min(30000, localmaxmp);
|
localmaxmp = Math.min(30000, localmaxmp);
|
||||||
|
|
||||||
if (ServerConstants.USE_FIXED_RATIO_HPMP_UPDATE) {
|
|
||||||
if (localmaxhp != oldlocalmaxhp) hpmpupdate.add(calcHpRatioUpdate(localmaxhp, oldlocalmaxhp));
|
|
||||||
if (localmaxmp != oldlocalmaxmp) hpmpupdate.add(calcMpRatioUpdate(localmaxmp, oldlocalmaxmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
MapleStatEffect combo = getBuffEffect(MapleBuffStat.ARAN_COMBO);
|
MapleStatEffect combo = getBuffEffect(MapleBuffStat.ARAN_COMBO);
|
||||||
if (combo != null) {
|
if (combo != null) {
|
||||||
localwatk += combo.getX();
|
localwatk += combo.getX();
|
||||||
@@ -6906,10 +6975,54 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
}
|
}
|
||||||
// Add throwing stars to dmg.
|
// Add throwing stars to dmg.
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
statWlock.unlock();
|
||||||
|
chrLock.unlock();
|
||||||
|
effLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Pair<MapleStat, Integer>> recalcLocalStats() {
|
||||||
|
effLock.lock();
|
||||||
|
chrLock.lock();
|
||||||
|
statWlock.lock();
|
||||||
|
try {
|
||||||
|
List<Pair<MapleStat, Integer>> hpmpupdate = new ArrayList<>(2);
|
||||||
|
int oldlocalmaxhp = localmaxhp;
|
||||||
|
int oldlocalmaxmp = localmaxmp;
|
||||||
|
|
||||||
|
reapplyLocalStats();
|
||||||
|
|
||||||
|
if (ServerConstants.USE_FIXED_RATIO_HPMP_UPDATE) {
|
||||||
|
if (localmaxhp != oldlocalmaxhp) {
|
||||||
|
Pair<MapleStat, Integer> hpUpdate;
|
||||||
|
|
||||||
|
if (transienthp == Float.NEGATIVE_INFINITY) {
|
||||||
|
hpUpdate = calcHpRatioUpdate(localmaxhp, oldlocalmaxhp);
|
||||||
|
} else {
|
||||||
|
hpUpdate = calcHpRatioTransient();
|
||||||
|
}
|
||||||
|
|
||||||
|
hpmpupdate.add(hpUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localmaxmp != oldlocalmaxmp) {
|
||||||
|
Pair<MapleStat, Integer> mpUpdate;
|
||||||
|
|
||||||
|
if (transientmp == Float.NEGATIVE_INFINITY) {
|
||||||
|
mpUpdate = calcMpRatioUpdate(localmaxmp, oldlocalmaxmp);
|
||||||
|
} else {
|
||||||
|
mpUpdate = calcMpRatioTransient();
|
||||||
|
}
|
||||||
|
|
||||||
|
hpmpupdate.add(mpUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return hpmpupdate;
|
return hpmpupdate;
|
||||||
} finally {
|
} finally {
|
||||||
statWlock.unlock();
|
statWlock.unlock();
|
||||||
|
chrLock.unlock();
|
||||||
effLock.unlock();
|
effLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7789,10 +7902,6 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChair(int chair) {
|
|
||||||
this.chair.set(chair);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChalkboard(String text) {
|
public void setChalkboard(String text) {
|
||||||
this.chalktext = text;
|
this.chalktext = text;
|
||||||
}
|
}
|
||||||
@@ -7968,7 +8077,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
|
|
||||||
private Pair<MapleStat, Integer> calcHpRatioUpdate(int newHp, int oldHp) {
|
private Pair<MapleStat, Integer> calcHpRatioUpdate(int newHp, int oldHp) {
|
||||||
int delta = newHp - oldHp;
|
int delta = newHp - oldHp;
|
||||||
this.hp = calcHpMpRatioUpdate(hp, oldHp, delta);
|
this.hp = calcHpRatioUpdate(hp, oldHp, delta);
|
||||||
|
|
||||||
hpChangeAction(Short.MIN_VALUE);
|
hpChangeAction(Short.MIN_VALUE);
|
||||||
return new Pair<>(MapleStat.HP, hp);
|
return new Pair<>(MapleStat.HP, hp);
|
||||||
@@ -7976,19 +8085,47 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
|
|
||||||
private Pair<MapleStat, Integer> calcMpRatioUpdate(int newMp, int oldMp) {
|
private Pair<MapleStat, Integer> calcMpRatioUpdate(int newMp, int oldMp) {
|
||||||
int delta = newMp - oldMp;
|
int delta = newMp - oldMp;
|
||||||
this.mp = calcHpMpRatioUpdate(mp, oldMp, delta);
|
this.mp = calcMpRatioUpdate(mp, oldMp, delta);
|
||||||
return new Pair<>(MapleStat.MP, mp);
|
return new Pair<>(MapleStat.MP, mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int calcHpMpRatioUpdate(int curpoint, int maxpoint, int diffpoint) {
|
private static int calcTransientRatio(float transientpoint) {
|
||||||
|
int ret = (int) transientpoint;
|
||||||
|
return !(ret <= 0 && transientpoint > 0.0f) ? ret : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<MapleStat, Integer> calcHpRatioTransient() {
|
||||||
|
this.hp = calcTransientRatio(transienthp * localmaxhp);
|
||||||
|
|
||||||
|
hpChangeAction(Short.MIN_VALUE);
|
||||||
|
return new Pair<>(MapleStat.HP, hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<MapleStat, Integer> calcMpRatioTransient() {
|
||||||
|
this.mp = calcTransientRatio(transientmp * localmaxmp);
|
||||||
|
return new Pair<>(MapleStat.MP, mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calcHpRatioUpdate(int curpoint, int maxpoint, int diffpoint) {
|
||||||
int curMax = maxpoint;
|
int curMax = maxpoint;
|
||||||
int nextMax = Math.min(30000, maxpoint + diffpoint);
|
int nextMax = Math.min(30000, maxpoint + diffpoint);
|
||||||
|
|
||||||
float temp = curpoint * nextMax;
|
float temp = curpoint * nextMax;
|
||||||
int ret = (int) Math.round(temp / curMax);
|
int ret = (int) Math.ceil(temp / curMax);
|
||||||
|
|
||||||
//System.out.println("cur: " + curpoint + " next: " + ret + " max: " + curMax + " nextmax:" + nextMax + " diff: " + diffpoint);
|
transienthp = (maxpoint > nextMax) ? ((float) curpoint) / maxpoint : ((float) ret) / nextMax;
|
||||||
return !(ret <= 0 && curpoint > 0) ? ret : 1;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calcMpRatioUpdate(int curpoint, int maxpoint, int diffpoint) {
|
||||||
|
int curMax = maxpoint;
|
||||||
|
int nextMax = Math.min(30000, maxpoint + diffpoint);
|
||||||
|
|
||||||
|
float temp = curpoint * nextMax;
|
||||||
|
int ret = (int) Math.ceil(temp / curMax);
|
||||||
|
|
||||||
|
transientmp = (maxpoint > nextMax) ? ((float) curpoint) / maxpoint : ((float) ret) / nextMax;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean applyHpMpChange(int hpCon, int hpchange, int mpchange) {
|
public boolean applyHpMpChange(int hpCon, int hpchange, int mpchange) {
|
||||||
@@ -8137,7 +8274,6 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
doorSlot = -1;
|
doorSlot = -1;
|
||||||
|
|
||||||
party = null;
|
party = null;
|
||||||
//cancelMagicDoor(); // cancel magic doors if kicked out / quitted from party.
|
|
||||||
} else {
|
} else {
|
||||||
party = p;
|
party = p;
|
||||||
}
|
}
|
||||||
@@ -9083,10 +9219,26 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
|||||||
pendantExp = 0;
|
pendantExp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Collection<Item> getUpgradeableEquipList() {
|
||||||
|
Collection<Item> fullList = getInventory(MapleInventoryType.EQUIPPED).list();
|
||||||
|
if (ServerConstants.USE_EQUIPMNT_LVLUP_CASH) {
|
||||||
|
return fullList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<Item> eqpList = new LinkedHashSet<>();
|
||||||
|
for (Item it : fullList) {
|
||||||
|
if (!ii.isCash(it.getItemId())) {
|
||||||
|
eqpList.add(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return eqpList;
|
||||||
|
}
|
||||||
|
|
||||||
public void increaseEquipExp(int expGain) {
|
public void increaseEquipExp(int expGain) {
|
||||||
if(expGain < 0) expGain = Integer.MAX_VALUE;
|
if(expGain < 0) expGain = Integer.MAX_VALUE;
|
||||||
|
|
||||||
for (Item item : getInventory(MapleInventoryType.EQUIPPED).list()) {
|
for (Item item : getUpgradeableEquipList()) {
|
||||||
Equip nEquip = (Equip) item;
|
Equip nEquip = (Equip) item;
|
||||||
String itemName = ii.getName(nEquip.getItemId());
|
String itemName = ii.getName(nEquip.getItemId());
|
||||||
if (itemName == null) {
|
if (itemName == null) {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
import tools.*;
|
import tools.*;
|
||||||
@@ -109,8 +110,10 @@ public class MapleClient {
|
|||||||
private String pic = null;
|
private String pic = null;
|
||||||
private String hwid = null;
|
private String hwid = null;
|
||||||
private int picattempt = 0;
|
private int picattempt = 0;
|
||||||
|
private byte csattempt = 0;
|
||||||
private byte gender = -1;
|
private byte gender = -1;
|
||||||
private boolean disconnecting = false;
|
private boolean disconnecting = false;
|
||||||
|
private final Semaphore actionsSemaphore = new Semaphore(7);
|
||||||
private final Lock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CLIENT, true);
|
private final Lock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CLIENT, true);
|
||||||
private final Lock encoderLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CLIENT_ENCODER, true);
|
private final Lock encoderLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CLIENT_ENCODER, true);
|
||||||
private static final Lock loginLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CLIENT_LOGIN, true);
|
private static final Lock loginLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CLIENT_LOGIN, true);
|
||||||
@@ -532,7 +535,6 @@ public class MapleClient {
|
|||||||
gender = rs.getByte("gender");
|
gender = rs.getByte("gender");
|
||||||
characterSlots = rs.getByte("characterslots");
|
characterSlots = rs.getByte("characterslots");
|
||||||
String passhash = rs.getString("password");
|
String passhash = rs.getString("password");
|
||||||
String salt = rs.getString("salt");
|
|
||||||
byte tos = rs.getByte("tos");
|
byte tos = rs.getByte("tos");
|
||||||
|
|
||||||
ps.close();
|
ps.close();
|
||||||
@@ -547,8 +549,9 @@ public class MapleClient {
|
|||||||
loginok = 7;
|
loginok = 7;
|
||||||
} else if (passhash.charAt(0) == '$' && passhash.charAt(1) == '2' && BCrypt.checkpw(pwd, passhash)) {
|
} else if (passhash.charAt(0) == '$' && passhash.charAt(1) == '2' && BCrypt.checkpw(pwd, passhash)) {
|
||||||
loginok = (tos == 0) ? 23 : 0;
|
loginok = (tos == 0) ? 23 : 0;
|
||||||
} else if (pwd.equals(passhash) || checkHash(passhash, "SHA-1", pwd) || checkHash(passhash, "SHA-512", pwd + salt)) {
|
} else if (pwd.equals(passhash) || checkHash(passhash, "SHA-1", pwd) || checkHash(passhash, "SHA-512", pwd)) {
|
||||||
loginok = (tos == 0) ? -23 : -10; // migrate to bcrypt
|
// thanks GabrielSin for detecting some no-bcrypt inconsistencies here
|
||||||
|
loginok = (tos == 0) ? (!ServerConstants.BCRYPT_MIGRATION ? 23 : -23) : (!ServerConstants.BCRYPT_MIGRATION ? 0 : -10); // migrate to bcrypt
|
||||||
} else {
|
} else {
|
||||||
loggedIn = false;
|
loggedIn = false;
|
||||||
loginok = 4;
|
loginok = 4;
|
||||||
@@ -775,7 +778,7 @@ public class MapleClient {
|
|||||||
if (!rs.next()) {
|
if (!rs.next()) {
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
throw new RuntimeException("getLoginState - MapleClient");
|
throw new RuntimeException("getLoginState - MapleClient AccID: " + getAccID());
|
||||||
}
|
}
|
||||||
|
|
||||||
birthday = Calendar.getInstance();
|
birthday = Calendar.getInstance();
|
||||||
@@ -1170,8 +1173,18 @@ public class MapleClient {
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean trylockClient() {
|
public boolean tryacquireClient() {
|
||||||
return lock.tryLock();
|
if (actionsSemaphore.tryAcquire()) {
|
||||||
|
lockClient();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void releaseClient() {
|
||||||
|
unlockClient();
|
||||||
|
actionsSemaphore.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lockEncoder() {
|
public void lockEncoder() {
|
||||||
@@ -1431,4 +1444,22 @@ public class MapleClient {
|
|||||||
this.removeClickedNPC();
|
this.removeClickedNPC();
|
||||||
NPCScriptManager.getInstance().dispose(this);
|
NPCScriptManager.getInstance().dispose(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean attemptCsCoupon() {
|
||||||
|
if (csattempt > 2) {
|
||||||
|
resetCsCoupon();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
csattempt++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetCsCoupon() {
|
||||||
|
csattempt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableCSActions() {
|
||||||
|
announce(MaplePacketCreator.enableCSUse(player));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-27
@@ -25,8 +25,9 @@ import java.sql.Connection;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import tools.Pair;
|
||||||
import tools.DatabaseConnection;
|
import tools.DatabaseConnection;
|
||||||
|
import client.inventory.manipulator.MapleCashidGenerator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -86,6 +87,9 @@ public class MapleRing implements Comparable<MapleRing> {
|
|||||||
ps.executeBatch();
|
ps.executeBatch();
|
||||||
ps.close();
|
ps.close();
|
||||||
|
|
||||||
|
MapleCashidGenerator.freeCashId(ring.getRingId());
|
||||||
|
MapleCashidGenerator.freeCashId(ring.getPartnerRingId());
|
||||||
|
|
||||||
ps = con.prepareStatement("UPDATE inventoryequipment SET ringid=-1 WHERE ringid=?");
|
ps = con.prepareStatement("UPDATE inventoryequipment SET ringid=-1 WHERE ringid=?");
|
||||||
ps.setInt(1, ring.getRingId());
|
ps.setInt(1, ring.getRingId());
|
||||||
ps.addBatch();
|
ps.addBatch();
|
||||||
@@ -102,46 +106,40 @@ public class MapleRing implements Comparable<MapleRing> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int createRing(int itemid, final MapleCharacter partner1, final MapleCharacter partner2) {
|
public static Pair<Integer, Integer> createRing(int itemid, final MapleCharacter partner1, final MapleCharacter partner2) {
|
||||||
try {
|
try {
|
||||||
if (partner1 == null) {
|
if (partner1 == null) {
|
||||||
return -2;
|
return new Pair<>(-3, -3);
|
||||||
} else if (partner2 == null) {
|
} else if (partner2 == null) {
|
||||||
return -1;
|
return new Pair<>(-2, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] ringID = new int[2];
|
int[] ringID = new int[2];
|
||||||
|
ringID[0] = MapleCashidGenerator.generateCashId();
|
||||||
|
ringID[1] = MapleCashidGenerator.generateCashId();
|
||||||
|
|
||||||
Connection con = DatabaseConnection.getConnection();
|
Connection con = DatabaseConnection.getConnection();
|
||||||
PreparedStatement ps = con.prepareStatement("INSERT INTO rings (itemid, partnerChrId, partnername) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
|
PreparedStatement ps = con.prepareStatement("INSERT INTO rings (id, itemid, partnerRingId, partnerChrId, partnername) VALUES (?, ?, ?, ?, ?)");
|
||||||
ps.setInt(1, itemid);
|
ps.setInt(1, ringID[0]);
|
||||||
ps.setInt(2, partner2.getId());
|
ps.setInt(2, itemid);
|
||||||
ps.setString(3, partner2.getName());
|
ps.setInt(3, ringID[1]);
|
||||||
|
ps.setInt(4, partner2.getId());
|
||||||
|
ps.setString(5, partner2.getName());
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
ResultSet rs = ps.getGeneratedKeys();
|
|
||||||
rs.next();
|
|
||||||
ringID[0] = rs.getInt(1); // ID.
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
ps.close();
|
||||||
ps = con.prepareStatement("INSERT INTO rings (itemid, partnerRingId, partnerChrId, partnername) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
|
ps = con.prepareStatement("INSERT INTO rings (id, itemid, partnerRingId, partnerChrId, partnername) VALUES (?, ?, ?, ?, ?)");
|
||||||
ps.setInt(1, itemid);
|
|
||||||
ps.setInt(2, ringID[0]);
|
|
||||||
ps.setInt(3, partner1.getId());
|
|
||||||
ps.setString(4, partner1.getName());
|
|
||||||
ps.executeUpdate();
|
|
||||||
rs = ps.getGeneratedKeys();
|
|
||||||
rs.next();
|
|
||||||
ringID[1] = rs.getInt(1);
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
ps = con.prepareStatement("UPDATE rings SET partnerRingId = ? WHERE id = ?");
|
|
||||||
ps.setInt(1, ringID[1]);
|
ps.setInt(1, ringID[1]);
|
||||||
ps.setInt(2, ringID[0]);
|
ps.setInt(2, itemid);
|
||||||
|
ps.setInt(3, ringID[0]);
|
||||||
|
ps.setInt(4, partner1.getId());
|
||||||
|
ps.setString(5, partner1.getName());
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
ps.close();
|
ps.close();
|
||||||
con.close();
|
con.close();
|
||||||
return ringID[0];
|
return new Pair<>(ringID[0], ringID[1]);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return -1;
|
return new Pair<>(-1, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package client.autoban;
|
|||||||
import client.MapleCharacter;
|
import client.MapleCharacter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import net.server.Server;
|
||||||
import tools.FilePrinter;
|
import tools.FilePrinter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,12 +36,12 @@ public class AutobanManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (lastTime.containsKey(fac)) {
|
if (lastTime.containsKey(fac)) {
|
||||||
if (lastTime.get(fac) < (System.currentTimeMillis() - fac.getExpire())) {
|
if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) {
|
||||||
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
|
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fac.getExpire() != -1)
|
if (fac.getExpire() != -1)
|
||||||
lastTime.put(fac, System.currentTimeMillis());
|
lastTime.put(fac, Server.getInstance().getCurrentTime());
|
||||||
|
|
||||||
if (points.containsKey(fac)) {
|
if (points.containsKey(fac)) {
|
||||||
points.put(fac, points.get(fac) + 1);
|
points.put(fac, points.get(fac) + 1);
|
||||||
@@ -76,7 +77,7 @@ public class AutobanManager {
|
|||||||
|
|
||||||
//Don't use the same type for more than 1 thing
|
//Don't use the same type for more than 1 thing
|
||||||
public void spam(int type) {
|
public void spam(int type) {
|
||||||
this.spam[type] = System.currentTimeMillis();
|
this.spam[type] = Server.getInstance().getCurrentTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spam(int type, int timestamp) {
|
public void spam(int type, int timestamp) {
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ public class CommandsExecutor {
|
|||||||
addCommand("droplimit", DropLimitCommand.class);
|
addCommand("droplimit", DropLimitCommand.class);
|
||||||
addCommand("time", TimeCommand.class);
|
addCommand("time", TimeCommand.class);
|
||||||
addCommand("credits", StaffCommand.class);
|
addCommand("credits", StaffCommand.class);
|
||||||
|
addCommand("buyback", BuyBackCommand.class);
|
||||||
addCommand("uptime", UptimeCommand.class);
|
addCommand("uptime", UptimeCommand.class);
|
||||||
addCommand("gacha", GachaCommand.class);
|
addCommand("gacha", GachaCommand.class);
|
||||||
addCommand("dispose", DisposeCommand.class);
|
addCommand("dispose", DisposeCommand.class);
|
||||||
@@ -345,6 +346,7 @@ public class CommandsExecutor {
|
|||||||
addCommand("shutdown", 6, ShutdownCommand.class);
|
addCommand("shutdown", 6, ShutdownCommand.class);
|
||||||
addCommand("clearquestcache", 6, ClearQuestCacheCommand.class);
|
addCommand("clearquestcache", 6, ClearQuestCacheCommand.class);
|
||||||
addCommand("clearquest", 6, ClearQuestCommand.class);
|
addCommand("clearquest", 6, ClearQuestCommand.class);
|
||||||
|
addCommand("supplyratecoupon", 6, SupplyRateCouponCommand.class);
|
||||||
addCommand("spawnallpnpcs", 6, SpawnAllPNpcsCommand.class);
|
addCommand("spawnallpnpcs", 6, SpawnAllPNpcsCommand.class);
|
||||||
addCommand("eraseallpnpcs", 6, EraseAllPNpcsCommand.class);
|
addCommand("eraseallpnpcs", 6, EraseAllPNpcsCommand.class);
|
||||||
addCommand("addchannel", 6, ServerAddChannelCommand.class);
|
addCommand("addchannel", 6, ServerAddChannelCommand.class);
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ import client.processor.BuybackProcessor;
|
|||||||
public class BuyBackCommand extends Command {
|
public class BuyBackCommand extends Command {
|
||||||
@Override
|
@Override
|
||||||
public void execute(MapleClient c, String[] params) {
|
public void execute(MapleClient c, String[] params) {
|
||||||
|
if (params.length < 1) {
|
||||||
|
c.getPlayer().yellowMessage("Syntax: @buyback <info|now>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params[0].contentEquals("now")) {
|
||||||
BuybackProcessor.processBuyback(c);
|
BuybackProcessor.processBuyback(c);
|
||||||
|
} else {
|
||||||
|
c.getPlayer().showBuybackInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class StatDexCommand extends Command {
|
|||||||
int remainingAp = player.getRemainingAp();
|
int remainingAp = player.getRemainingAp();
|
||||||
|
|
||||||
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getDex());
|
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getDex());
|
||||||
if (!player.assignDex(amount)) {
|
if (!player.assignDex(Math.max(amount, 0))) {
|
||||||
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class StatIntCommand extends Command {
|
|||||||
int remainingAp = player.getRemainingAp();
|
int remainingAp = player.getRemainingAp();
|
||||||
|
|
||||||
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getInt());
|
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getInt());
|
||||||
if (!player.assignInt(amount)) {
|
if (!player.assignInt(Math.max(amount, 0))) {
|
||||||
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class StatLukCommand extends Command {
|
|||||||
int remainingAp = player.getRemainingAp();
|
int remainingAp = player.getRemainingAp();
|
||||||
|
|
||||||
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getLuk());
|
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getLuk());
|
||||||
if (!player.assignLuk(amount)) {
|
if (!player.assignLuk(Math.max(amount, 0))) {
|
||||||
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class StatStrCommand extends Command {
|
|||||||
int remainingAp = player.getRemainingAp();
|
int remainingAp = player.getRemainingAp();
|
||||||
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getStr());
|
int amount = (params.length > 0) ? Math.min(Integer.parseInt(params[0]), remainingAp) : Math.min(remainingAp, ServerConstants.MAX_AP - player.getStr());
|
||||||
|
|
||||||
if (!player.assignStr(amount)) {
|
if (!player.assignStr(Math.max(amount, 0))) {
|
||||||
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
player.dropMessage("Please make sure your AP is not over " + ServerConstants.MAX_AP + " and you have enough to distribute.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ public class WhoDropsCommand extends Command {
|
|||||||
player.dropMessage(5, "Please do @whodrops <item name>");
|
player.dropMessage(5, "Please do @whodrops <item name>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c.tryacquireClient()) {
|
||||||
|
try {
|
||||||
String searchString = joinStringFrom(params, 0);
|
String searchString = joinStringFrom(params, 0);
|
||||||
String output = "";
|
String output = "";
|
||||||
Iterator<Pair<Integer, String>> listIterator = MapleItemInformationProvider.getInstance().getItemDataByName(searchString).iterator();
|
Iterator<Pair<Integer, String>> listIterator = MapleItemInformationProvider.getInstance().getItemDataByName(searchString).iterator();
|
||||||
@@ -84,5 +87,11 @@ public class WhoDropsCommand extends Command {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c.announce(MaplePacketCreator.getNPCTalk(9010000, (byte) 0, output, "00 00", (byte) 0));
|
c.announce(MaplePacketCreator.getNPCTalk(9010000, (byte) 0, output, "00 00", (byte) 0));
|
||||||
|
} finally {
|
||||||
|
c.releaseClient();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.dropMessage(5, "Please wait a while for your request to be processed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ public class ItemDropCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item toDrop;
|
Item toDrop;
|
||||||
if (ItemConstants.getInventoryType(itemId) == MapleInventoryType.EQUIP) {
|
if (ItemConstants.getInventoryType(itemId) == MapleInventoryType.EQUIP) {
|
||||||
toDrop = ii.getEquipById(itemId);
|
toDrop = ii.getEquipById(itemId);
|
||||||
|
|||||||
@@ -37,8 +37,19 @@ import tools.Pair;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public class SearchCommand extends Command {
|
public class SearchCommand extends Command {
|
||||||
|
private static MapleData npcStringData;
|
||||||
|
private static MapleData mobStringData;
|
||||||
|
private static MapleData skillStringData;
|
||||||
|
private static MapleData mapStringData;
|
||||||
|
|
||||||
{
|
{
|
||||||
setDescription("");
|
setDescription("");
|
||||||
|
|
||||||
|
MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File("wz/String.wz"));
|
||||||
|
npcStringData = dataProvider.getData("Npc.img");
|
||||||
|
mobStringData = dataProvider.getData("Mob.img");
|
||||||
|
skillStringData = dataProvider.getData("Skill.img");
|
||||||
|
mapStringData = dataProvider.getData("Map.img");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -53,28 +64,45 @@ public class SearchCommand extends Command {
|
|||||||
String search = joinStringFrom(params,1);
|
String search = joinStringFrom(params,1);
|
||||||
long start = System.currentTimeMillis();//for the lulz
|
long start = System.currentTimeMillis();//for the lulz
|
||||||
MapleData data = null;
|
MapleData data = null;
|
||||||
MapleDataProvider dataProvider = MapleDataProviderFactory.getDataProvider(new File("wz/String.wz"));
|
|
||||||
if (!params[0].equalsIgnoreCase("ITEM")) {
|
if (!params[0].equalsIgnoreCase("ITEM")) {
|
||||||
|
boolean mapSearch = false;
|
||||||
|
|
||||||
if (params[0].equalsIgnoreCase("NPC")) {
|
if (params[0].equalsIgnoreCase("NPC")) {
|
||||||
data = dataProvider.getData("Npc.img");
|
data = npcStringData;
|
||||||
} else if (params[0].equalsIgnoreCase("MOB") || params[0].equalsIgnoreCase("MONSTER")) {
|
} else if (params[0].equalsIgnoreCase("MOB") || params[0].equalsIgnoreCase("MONSTER")) {
|
||||||
data = dataProvider.getData("Mob.img");
|
data = mobStringData;
|
||||||
} else if (params[0].equalsIgnoreCase("SKILL")) {
|
} else if (params[0].equalsIgnoreCase("SKILL")) {
|
||||||
data = dataProvider.getData("Skill.img");
|
data = skillStringData;
|
||||||
/*} else if (sub[1].equalsIgnoreCase("MAP")) {
|
} else if (params[0].equalsIgnoreCase("MAP")) {
|
||||||
TODO
|
data = mapStringData;
|
||||||
*/
|
mapSearch = true;
|
||||||
} else {
|
} else {
|
||||||
sb.append("#bInvalid search.\r\nSyntax: '!search [type] [name]', where [type] is NPC, ITEM, MOB, or SKILL.");
|
sb.append("#bInvalid search.\r\nSyntax: '!search [type] [name]', where [type] is MAP, NPC, ITEM, MOB, or SKILL.");
|
||||||
}
|
}
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
String name;
|
String name;
|
||||||
|
|
||||||
|
if (!mapSearch) {
|
||||||
for (MapleData searchData : data.getChildren()) {
|
for (MapleData searchData : data.getChildren()) {
|
||||||
name = MapleDataTool.getString(searchData.getChildByPath("name"), "NO-NAME");
|
name = MapleDataTool.getString(searchData.getChildByPath("name"), "NO-NAME");
|
||||||
if (name.toLowerCase().contains(search.toLowerCase())) {
|
if (name.toLowerCase().contains(search.toLowerCase())) {
|
||||||
sb.append("#b").append(Integer.parseInt(searchData.getName())).append("#k - #r").append(name).append("\r\n");
|
sb.append("#b").append(Integer.parseInt(searchData.getName())).append("#k - #r").append(name).append("\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
String mapName, streetName;
|
||||||
|
|
||||||
|
for (MapleData searchDataDir : data.getChildren()) {
|
||||||
|
for (MapleData searchData : searchDataDir.getChildren()) {
|
||||||
|
mapName = MapleDataTool.getString(searchData.getChildByPath("mapName"), "NO-NAME");
|
||||||
|
streetName = MapleDataTool.getString(searchData.getChildByPath("streetName"), "NO-NAME");
|
||||||
|
|
||||||
|
if (mapName.toLowerCase().contains(search.toLowerCase()) || streetName.toLowerCase().contains(search.toLowerCase())) {
|
||||||
|
sb.append("#b").append(Integer.parseInt(searchData.getName())).append("#k - #r").append(streetName).append(" - ").append(mapName).append("\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Pair<Integer, String> itemPair : MapleItemInformationProvider.getInstance().getAllItems()) {
|
for (Pair<Integer, String> itemPair : MapleItemInformationProvider.getInstance().getAllItems()) {
|
||||||
|
|||||||
+11
-9
@@ -17,25 +17,27 @@
|
|||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
@Author: Arthur L - Refactored command content into modules
|
|
||||||
*/
|
|
||||||
package client.command.commands.gm6;
|
package client.command.commands.gm6;
|
||||||
|
|
||||||
import client.command.Command;
|
|
||||||
import client.MapleClient;
|
|
||||||
import client.MapleCharacter;
|
import client.MapleCharacter;
|
||||||
import tools.MaplePacketCreator;
|
import client.MapleClient;
|
||||||
|
import client.command.Command;
|
||||||
|
import constants.ServerConstants;
|
||||||
|
|
||||||
public class FredCommand extends Command {
|
public class SupplyRateCouponCommand extends Command {
|
||||||
{
|
{
|
||||||
setDescription("");
|
setDescription("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(MapleClient c, String[] params) {
|
public void execute(MapleClient c, String[] params) {
|
||||||
c.announce(MaplePacketCreator.fredrickMessage(Byte.valueOf(params[0])));
|
MapleCharacter player = c.getPlayer();
|
||||||
|
if (params.length < 1) {
|
||||||
|
player.dropMessage(5, "Syntax: !supplyratecoupon <yes|no>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerConstants.USE_SUPPLY_RATE_COUPONS = params[0].compareToIgnoreCase("no") != 0;
|
||||||
|
player.dropMessage(5, "Rate coupons are now " + (ServerConstants.USE_SUPPLY_RATE_COUPONS ? "enabled" : "disabled") + " for purchase at the Cash Shop.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,10 +26,12 @@ import java.util.Collections;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import client.inventory.manipulator.MapleKarmaManipulator;
|
||||||
|
import server.MapleItemInformationProvider;
|
||||||
|
|
||||||
public class Item implements Comparable<Item> {
|
public class Item implements Comparable<Item> {
|
||||||
|
|
||||||
private static AtomicInteger runningCashId = new AtomicInteger(0);
|
private static AtomicInteger runningCashId = new AtomicInteger(777000000); // pets & rings shares cashid values
|
||||||
|
|
||||||
private int id, cashId, sn;
|
private int id, cashId, sn;
|
||||||
private short position;
|
private short position;
|
||||||
@@ -83,7 +85,7 @@ public class Item implements Comparable<Item> {
|
|||||||
|
|
||||||
public int getCashId() {
|
public int getCashId() {
|
||||||
if (cashId == 0) {
|
if (cashId == 0) {
|
||||||
cashId = runningCashId.incrementAndGet();
|
cashId = runningCashId.getAndIncrement();
|
||||||
}
|
}
|
||||||
return cashId;
|
return cashId;
|
||||||
}
|
}
|
||||||
@@ -177,4 +179,8 @@ public class Item implements Comparable<Item> {
|
|||||||
public MaplePet getPet() {
|
public MaplePet getPet() {
|
||||||
return pet;
|
return pet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isUntradeable() {
|
||||||
|
return ((this.getFlag() & ItemConstants.UNTRADEABLE) == ItemConstants.UNTRADEABLE) || (MapleItemInformationProvider.getInstance().isDropRestricted(this.getItemId()) && !MapleKarmaManipulator.hasKarmaFlag(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
package client.inventory;
|
package client.inventory;
|
||||||
|
|
||||||
import com.mysql.jdbc.Statement;
|
|
||||||
import constants.ExpTable;
|
import constants.ExpTable;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
@@ -34,6 +33,7 @@ import server.movement.AbsoluteLifeMovement;
|
|||||||
import server.movement.LifeMovement;
|
import server.movement.LifeMovement;
|
||||||
import server.movement.LifeMovementFragment;
|
import server.movement.LifeMovementFragment;
|
||||||
import client.MapleCharacter;
|
import client.MapleCharacter;
|
||||||
|
import client.inventory.manipulator.MapleCashidGenerator;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import tools.MaplePacketCreator;
|
import tools.MaplePacketCreator;
|
||||||
import tools.Pair;
|
import tools.Pair;
|
||||||
@@ -90,6 +90,8 @@ public class MaplePet extends Item {
|
|||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
ps.close();
|
ps.close();
|
||||||
con.close();
|
con.close();
|
||||||
|
|
||||||
|
MapleCashidGenerator.freeCashId(this.getUniqueId());
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -116,15 +118,11 @@ public class MaplePet extends Item {
|
|||||||
public static int createPet(int itemid) {
|
public static int createPet(int itemid) {
|
||||||
try {
|
try {
|
||||||
Connection con = DatabaseConnection.getConnection();
|
Connection con = DatabaseConnection.getConnection();
|
||||||
PreparedStatement ps = con.prepareStatement("INSERT INTO pets (name, level, closeness, fullness, summoned) VALUES (?, 1, 0, 100, 0)", Statement.RETURN_GENERATED_KEYS);
|
PreparedStatement ps = con.prepareStatement("INSERT INTO pets (petid, name, level, closeness, fullness, summoned) VALUES (?, ?, 1, 0, 100, 0)");
|
||||||
ps.setString(1, MapleItemInformationProvider.getInstance().getName(itemid));
|
int ret = MapleCashidGenerator.generateCashId();
|
||||||
|
ps.setInt(1, ret);
|
||||||
|
ps.setString(2, MapleItemInformationProvider.getInstance().getName(itemid));
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
ResultSet rs = ps.getGeneratedKeys();
|
|
||||||
int ret = -1;
|
|
||||||
if (rs.next()) {
|
|
||||||
ret = rs.getInt(1);
|
|
||||||
}
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
ps.close();
|
||||||
con.close();
|
con.close();
|
||||||
return ret;
|
return ret;
|
||||||
@@ -137,18 +135,14 @@ public class MaplePet extends Item {
|
|||||||
public static int createPet(int itemid, byte level, int closeness, int fullness) {
|
public static int createPet(int itemid, byte level, int closeness, int fullness) {
|
||||||
try {
|
try {
|
||||||
Connection con = DatabaseConnection.getConnection();
|
Connection con = DatabaseConnection.getConnection();
|
||||||
PreparedStatement ps = con.prepareStatement("INSERT INTO pets (name, level, closeness, fullness, summoned) VALUES (?, ?, ?, ?, 0)", Statement.RETURN_GENERATED_KEYS);
|
PreparedStatement ps = con.prepareStatement("INSERT INTO pets (petid, name, level, closeness, fullness, summoned) VALUES (?, ?, ?, ?, ?, 0)");
|
||||||
ps.setString(1, MapleItemInformationProvider.getInstance().getName(itemid));
|
int ret = MapleCashidGenerator.generateCashId();
|
||||||
ps.setByte(2, level);
|
ps.setInt(1, ret);
|
||||||
ps.setInt(3, closeness);
|
ps.setString(2, MapleItemInformationProvider.getInstance().getName(itemid));
|
||||||
ps.setInt(4, fullness);
|
ps.setByte(3, level);
|
||||||
|
ps.setInt(4, closeness);
|
||||||
|
ps.setInt(5, fullness);
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
ResultSet rs = ps.getGeneratedKeys();
|
|
||||||
int ret = -1;
|
|
||||||
if (rs.next()) {
|
|
||||||
ret = rs.getInt(1);
|
|
||||||
}
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
ps.close();
|
||||||
con.close();
|
con.close();
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
This file is part of the HeavenMS MapleStory Server
|
||||||
|
Copyleft (L) 2016 - 2018 RonanLana
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation version 3 as published by
|
||||||
|
the Free Software Foundation. You may not use, modify or distribute
|
||||||
|
this program under any other version of the GNU Affero General Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package client.inventory.manipulator;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import tools.DatabaseConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author RonanLana
|
||||||
|
*/
|
||||||
|
public class MapleCashidGenerator {
|
||||||
|
|
||||||
|
private final static Set<Integer> existentCashids = new HashSet<>(10000);
|
||||||
|
private static Integer runningCashid = 0;
|
||||||
|
|
||||||
|
private static void loadExistentCashIdsFromQuery(Connection con, String query) throws SQLException {
|
||||||
|
PreparedStatement ps = con.prepareStatement(query);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
existentCashids.add(rs.getInt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void loadExistentCashIdsFromDb() {
|
||||||
|
Connection con = null;
|
||||||
|
try {
|
||||||
|
con = DatabaseConnection.getConnection();
|
||||||
|
|
||||||
|
loadExistentCashIdsFromQuery(con, "SELECT id FROM rings");
|
||||||
|
loadExistentCashIdsFromQuery(con, "SELECT petid FROM pets");
|
||||||
|
|
||||||
|
con.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (con != null && !con.isClosed()) {
|
||||||
|
con.close();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runningCashid = 0;
|
||||||
|
do {
|
||||||
|
runningCashid++; // hopefully the id will never surpass the allotted amount for pets/rings?
|
||||||
|
} while (existentCashids.contains(runningCashid));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getNextAvailableCashId() {
|
||||||
|
runningCashid++;
|
||||||
|
if (runningCashid >= 777000000) {
|
||||||
|
existentCashids.clear();
|
||||||
|
loadExistentCashIdsFromDb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized int generateCashId() {
|
||||||
|
while (true) {
|
||||||
|
if (!existentCashids.contains(runningCashid)) {
|
||||||
|
int ret = runningCashid;
|
||||||
|
getNextAvailableCashId();
|
||||||
|
|
||||||
|
// existentCashids.add(ret)... no need to do this since the wrap over already refetches already used cashids from the DB
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getNextAvailableCashId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void freeCashId(int cashId) {
|
||||||
|
existentCashids.remove(cashId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -520,17 +520,19 @@ public class MapleInventoryManipulator {
|
|||||||
|
|
||||||
//1112413, 1112414, 1112405 (Lilin's Ring)
|
//1112413, 1112414, 1112405 (Lilin's Ring)
|
||||||
source = (Equip) eqpInv.getItem(src);
|
source = (Equip) eqpInv.getItem(src);
|
||||||
Equip target = (Equip) eqpdInv.getItem(dst);
|
|
||||||
eqpInv.removeSlot(src);
|
eqpInv.removeSlot(src);
|
||||||
if (target != null) {
|
|
||||||
|
Equip target;
|
||||||
eqpdInv.lockInventory();
|
eqpdInv.lockInventory();
|
||||||
try {
|
try {
|
||||||
|
target = (Equip) eqpdInv.getItem(dst);
|
||||||
|
if (target != null) {
|
||||||
chr.unequippedItem(target);
|
chr.unequippedItem(target);
|
||||||
eqpdInv.removeSlot(dst);
|
eqpdInv.removeSlot(dst);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
eqpdInv.unlockInventory();
|
eqpdInv.unlockInventory();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final List<ModifyInventory> mods = new ArrayList<>();
|
final List<ModifyInventory> mods = new ArrayList<>();
|
||||||
if (itemChanged) {
|
if (itemChanged) {
|
||||||
@@ -705,7 +707,7 @@ public class MapleInventoryManipulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isDroppedItemRestricted(Item it) {
|
private static boolean isDroppedItemRestricted(Item it) {
|
||||||
return ServerConstants.USE_ERASE_UNTRADEABLE_DROP && ((it.getFlag() & ItemConstants.UNTRADEABLE) == ItemConstants.UNTRADEABLE);
|
return ServerConstants.USE_ERASE_UNTRADEABLE_DROP && it.isUntradeable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSandboxItem(Item it) {
|
public static boolean isSandboxItem(Item it) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class AssignSPProcessor {
|
|||||||
c.lockClient();
|
c.lockClient();
|
||||||
try {
|
try {
|
||||||
if (skillid == Aran.HIDDEN_FULL_DOUBLE || skillid == Aran.HIDDEN_FULL_TRIPLE || skillid == Aran.HIDDEN_OVER_DOUBLE || skillid == Aran.HIDDEN_OVER_TRIPLE) {
|
if (skillid == Aran.HIDDEN_FULL_DOUBLE || skillid == Aran.HIDDEN_FULL_TRIPLE || skillid == Aran.HIDDEN_OVER_DOUBLE || skillid == Aran.HIDDEN_OVER_TRIPLE) {
|
||||||
c.getSession().write(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,16 +21,13 @@ package client.processor;
|
|||||||
|
|
||||||
import client.MapleClient;
|
import client.MapleClient;
|
||||||
import client.MapleCharacter;
|
import client.MapleCharacter;
|
||||||
import client.MapleStat;
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import server.maps.MapleMap;
|
import server.maps.MapleMap;
|
||||||
import server.movement.AbsoluteLifeMovement;
|
import server.movement.AbsoluteLifeMovement;
|
||||||
import server.movement.LifeMovementFragment;
|
import server.movement.LifeMovementFragment;
|
||||||
import tools.MaplePacketCreator;
|
import tools.MaplePacketCreator;
|
||||||
import tools.Pair;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ public class DueyProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void dueySendItem(MapleClient c, byte inventId, short itemPos, short amount, int mesos, String recipient) {
|
public static void dueySendItem(MapleClient c, byte inventId, short itemPos, short amount, int mesos, String recipient) {
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
final int fee = 5000;
|
final int fee = 5000;
|
||||||
final long sendMesos = (long) mesos + fee;
|
final long sendMesos = (long) mesos + fee;
|
||||||
@@ -417,22 +417,24 @@ public class DueyProcessor {
|
|||||||
showDueyNotification(rClient, rClient.getPlayer());
|
showDueyNotification(rClient, rClient.getPlayer());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dueyRemovePackage(MapleClient c, int packageid) {
|
public static void dueyRemovePackage(MapleClient c, int packageid) {
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
removeItemFromDB(packageid);
|
removeItemFromDB(packageid);
|
||||||
c.announce(MaplePacketCreator.removeItemFromDuey(true, packageid));
|
c.announce(MaplePacketCreator.removeItemFromDuey(true, packageid));
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dueyClaimPackage(MapleClient c, int packageid) {
|
public static void dueyClaimPackage(MapleClient c, int packageid) {
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
List<DueyPackages> packages = new LinkedList<>();
|
List<DueyPackages> packages = new LinkedList<>();
|
||||||
DueyPackages dp = null;
|
DueyPackages dp = null;
|
||||||
@@ -496,16 +498,18 @@ public class DueyProcessor {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dueySendTalk(MapleClient c) {
|
public static void dueySendTalk(MapleClient c) {
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
c.announce(MaplePacketCreator.sendDuey((byte) 8, loadItems(c.getPlayer())));
|
c.announce(MaplePacketCreator.sendDuey((byte) 8, loadItems(c.getPlayer())));
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class FredrickProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void fredrickRetrieveItems(MapleClient c) { // thanks Gustav for pointing out the dupe on Fredrick handling
|
public static void fredrickRetrieveItems(MapleClient c) { // thanks Gustav for pointing out the dupe on Fredrick handling
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
MapleCharacter chr = c.getPlayer();
|
MapleCharacter chr = c.getPlayer();
|
||||||
|
|
||||||
@@ -105,7 +105,8 @@ public class FredrickProcessor {
|
|||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import client.inventory.MapleInventoryType;
|
|||||||
import constants.ItemConstants;
|
import constants.ItemConstants;
|
||||||
import constants.ServerConstants;
|
import constants.ServerConstants;
|
||||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||||
import constants.EquipType;
|
|
||||||
import constants.GameConstants;
|
import constants.GameConstants;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -47,7 +46,7 @@ public class MakerProcessor {
|
|||||||
private static MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
private static MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||||
|
|
||||||
public static void makerAction(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public static void makerAction(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
int type = slea.readInt();
|
int type = slea.readInt();
|
||||||
int toCreate = slea.readInt();
|
int toCreate = slea.readInt();
|
||||||
@@ -208,7 +207,8 @@ public class MakerProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class SpawnPetProcessor {
|
|||||||
private static MapleDataProvider dataRoot = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Item.wz"));
|
private static MapleDataProvider dataRoot = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Item.wz"));
|
||||||
|
|
||||||
public static void processSpawnPet(MapleClient c, byte slot, boolean lead) {
|
public static void processSpawnPet(MapleClient c, byte slot, boolean lead) {
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
MapleCharacter chr = c.getPlayer();
|
MapleCharacter chr = c.getPlayer();
|
||||||
MaplePet pet = chr.getInventory(MapleInventoryType.CASH).getItem(slot).getPet();
|
MaplePet pet = chr.getInventory(MapleInventoryType.CASH).getItem(slot).getPet();
|
||||||
@@ -93,7 +93,8 @@ public class SpawnPetProcessor {
|
|||||||
chr.getClient().getWorldServer().registerPetHunger(chr, chr.getPetIndex(pet));
|
chr.getClient().getWorldServer().registerPetHunger(chr, chr.getPetIndex(pet));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class StorageProcessor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
if (mode == 4) { // take out
|
if (mode == 4) { // take out
|
||||||
byte type = slea.readByte();
|
byte type = slea.readByte();
|
||||||
@@ -145,13 +145,13 @@ public class StorageProcessor {
|
|||||||
int playerMesos = chr.getMeso();
|
int playerMesos = chr.getMeso();
|
||||||
if ((meso > 0 && storageMesos >= meso) || (meso < 0 && playerMesos >= -meso)) {
|
if ((meso > 0 && storageMesos >= meso) || (meso < 0 && playerMesos >= -meso)) {
|
||||||
if (meso < 0 && (storageMesos - meso) < 0) {
|
if (meso < 0 && (storageMesos - meso) < 0) {
|
||||||
meso = -2147483648 + storageMesos;
|
meso = Integer.MIN_VALUE + storageMesos;
|
||||||
if (meso < playerMesos) {
|
if (meso < playerMesos) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (meso > 0 && (playerMesos + meso) < 0) {
|
} else if (meso > 0 && (playerMesos + meso) < 0) {
|
||||||
meso = 2147483647 - playerMesos;
|
meso = Integer.MAX_VALUE - playerMesos;
|
||||||
if (meso > storageMesos) {
|
if (meso > storageMesos) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
return;
|
return;
|
||||||
@@ -170,7 +170,8 @@ public class StorageProcessor {
|
|||||||
storage.close();
|
storage.close();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public class ServerConstants {
|
|||||||
public static final boolean USE_DEBUG = false; //Will enable some text prints on the client, oriented for debugging purposes.
|
public static final boolean USE_DEBUG = false; //Will enable some text prints on the client, oriented for debugging purposes.
|
||||||
public static final boolean USE_DEBUG_SHOW_INFO_EQPEXP = false; //Prints on the cmd all equip exp gain info.
|
public static final boolean USE_DEBUG_SHOW_INFO_EQPEXP = false; //Prints on the cmd all equip exp gain info.
|
||||||
public static boolean USE_DEBUG_SHOW_RCVD_PACKET = false; //Prints on the cmd all received packet ids.
|
public static boolean USE_DEBUG_SHOW_RCVD_PACKET = false; //Prints on the cmd all received packet ids.
|
||||||
|
public static boolean USE_SUPPLY_RATE_COUPONS = true; //Allows rate coupons to be sold through the Cash Shop.
|
||||||
|
|
||||||
public static final boolean USE_MAXRANGE = true; //Will send and receive packets from all events on a map, rather than those of only view range.
|
public static final boolean USE_MAXRANGE = true; //Will send and receive packets from all events on a map, rather than those of only view range.
|
||||||
public static final boolean USE_MAXRANGE_ECHO_OF_HERO = true;
|
public static final boolean USE_MAXRANGE_ECHO_OF_HERO = true;
|
||||||
@@ -104,6 +105,7 @@ public class ServerConstants {
|
|||||||
|
|
||||||
//Cash Shop Configuration
|
//Cash Shop Configuration
|
||||||
public static final boolean USE_JOINT_CASHSHOP_INVENTORY = true;//Enables usage of a same cash shop inventory for explorers, cygnus and legends. Items from exclusive cash shop inventories won't show up on the shared inventory, though.
|
public static final boolean USE_JOINT_CASHSHOP_INVENTORY = true;//Enables usage of a same cash shop inventory for explorers, cygnus and legends. Items from exclusive cash shop inventories won't show up on the shared inventory, though.
|
||||||
|
public static final boolean USE_CLEAR_OUTDATED_COUPONS = true; //Enables deletion of older code coupon registry from the DB, freeing so-long irrelevant data.
|
||||||
|
|
||||||
//Maker Configuration
|
//Maker Configuration
|
||||||
public static final boolean USE_MAKER_PERMISSIVE_ATKUP = true; //Allows players to use attack-based strengthening gems on non-weapon items.
|
public static final boolean USE_MAKER_PERMISSIVE_ATKUP = true; //Allows players to use attack-based strengthening gems on non-weapon items.
|
||||||
@@ -149,6 +151,7 @@ public class ServerConstants {
|
|||||||
public static final int ITEM_EXPIRE_CHECK = 10 * 1000; //Interval between item expiring tasks on maps, which checks and makes disappear expired items.
|
public static final int ITEM_EXPIRE_CHECK = 10 * 1000; //Interval between item expiring tasks on maps, which checks and makes disappear expired items.
|
||||||
public static final int ITEM_LIMIT_ON_MAP = 200; //Max number of items allowed on a map.
|
public static final int ITEM_LIMIT_ON_MAP = 200; //Max number of items allowed on a map.
|
||||||
public static final int MAP_VISITED_SIZE = 5; //Max length for last mapids visited by a player. This is used to recover and update drops on these maps accordingly with player actions.
|
public static final int MAP_VISITED_SIZE = 5; //Max length for last mapids visited by a player. This is used to recover and update drops on these maps accordingly with player actions.
|
||||||
|
public static final int MAP_DAMAGE_OVERTIME_INTERVAL = 5000;//Interval in seconds between map environment damage (e.g. El Nath and Aqua Road surrondings).
|
||||||
|
|
||||||
//Channel Mob Disease Monitor Configuration
|
//Channel Mob Disease Monitor Configuration
|
||||||
public static final int MOB_STATUS_MONITOR_PROC = 200; //Frequency in milliseconds between each proc on the mob disease monitor schedule.
|
public static final int MOB_STATUS_MONITOR_PROC = 200; //Frequency in milliseconds between each proc on the mob disease monitor schedule.
|
||||||
@@ -172,7 +175,7 @@ public class ServerConstants {
|
|||||||
|
|
||||||
//Other Skills Configuration
|
//Other Skills Configuration
|
||||||
public static final boolean USE_FAST_REUSE_HERO_WILL = true;//Greatly reduce cooldown on Hero's Will.
|
public static final boolean USE_FAST_REUSE_HERO_WILL = true;//Greatly reduce cooldown on Hero's Will.
|
||||||
public static final boolean USE_ANTI_IMMUNITY_CRASH = true; //Crash skills additionally removes the mob's invincibility buffs.
|
public static final boolean USE_ANTI_IMMUNITY_CRASH = true; //Crash skills additionally removes the mob's invincibility buffs. Suggestion thanks to Celestial.
|
||||||
public static final boolean USE_UNDISPEL_HOLY_SHIELD = true;//Holy shield buff also prevents players from suffering dispel from mobs.
|
public static final boolean USE_UNDISPEL_HOLY_SHIELD = true;//Holy shield buff also prevents players from suffering dispel from mobs.
|
||||||
|
|
||||||
//Character Configuration
|
//Character Configuration
|
||||||
@@ -200,6 +203,7 @@ public class ServerConstants {
|
|||||||
//Equipment Configuration
|
//Equipment Configuration
|
||||||
public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up.
|
public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up.
|
||||||
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stat upgrades at equip level up.
|
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stat upgrades at equip level up.
|
||||||
|
public static final boolean USE_EQUIPMNT_LVLUP_CASH = true; //Enable equip leveling up on cash equipments as well.
|
||||||
public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes prevents mobs from banishing wearer.
|
public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes prevents mobs from banishing wearer.
|
||||||
public static final int MAX_EQUIPMNT_LVLUP_STAT_UP = 10000; //Max stat upgrade an equipment can have on a levelup.
|
public static final int MAX_EQUIPMNT_LVLUP_STAT_UP = 10000; //Max stat upgrade an equipment can have on a levelup.
|
||||||
public static final int MAX_EQUIPMNT_STAT = 32767; //Max stat on an equipment by leveling up.
|
public static final int MAX_EQUIPMNT_STAT = 32767; //Max stat on an equipment by leveling up.
|
||||||
|
|||||||
@@ -33,6 +33,5 @@ public class SuperGM {
|
|||||||
public static final int HIDE = 9101004;
|
public static final int HIDE = 9101004;
|
||||||
public static final int RESURRECTION = 9101005;
|
public static final int RESURRECTION = 9101005;
|
||||||
public static final int SUPER_DRAGON_ROAR = 9001001;
|
public static final int SUPER_DRAGON_ROAR = 9001001;
|
||||||
public static final int TELEPORT = 9101007;
|
|
||||||
public static final int HYPER_BODY = 9101008;
|
public static final int HYPER_BODY = 9101008;
|
||||||
}
|
}
|
||||||
+33
-12
@@ -80,6 +80,7 @@ import client.MapleCharacter;
|
|||||||
import client.SkillFactory;
|
import client.SkillFactory;
|
||||||
import client.inventory.Item;
|
import client.inventory.Item;
|
||||||
import client.inventory.ItemFactory;
|
import client.inventory.ItemFactory;
|
||||||
|
import client.inventory.manipulator.MapleCashidGenerator;
|
||||||
import client.newyear.NewYearCardRecord;
|
import client.newyear.NewYearCardRecord;
|
||||||
import constants.ItemConstants;
|
import constants.ItemConstants;
|
||||||
import constants.GameConstants;
|
import constants.GameConstants;
|
||||||
@@ -90,7 +91,6 @@ import server.life.MaplePlayerNPCFactory;
|
|||||||
import server.quest.MapleQuest;
|
import server.quest.MapleQuest;
|
||||||
import tools.AutoJCE;
|
import tools.AutoJCE;
|
||||||
import tools.DatabaseConnection;
|
import tools.DatabaseConnection;
|
||||||
import tools.FilePrinter;
|
|
||||||
import tools.Pair;
|
import tools.Pair;
|
||||||
|
|
||||||
public class Server {
|
public class Server {
|
||||||
@@ -518,6 +518,34 @@ public class Server {
|
|||||||
return couponRates;
|
return couponRates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void cleanNxcodeCoupons(Connection con) throws SQLException {
|
||||||
|
if (!ServerConstants.USE_CLEAR_OUTDATED_COUPONS) return;
|
||||||
|
|
||||||
|
long timeClear = System.currentTimeMillis() - 14 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT * FROM nxcode WHERE expiration <= ?");
|
||||||
|
ps.setLong(1, timeClear);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
|
||||||
|
if (!rs.isLast()) {
|
||||||
|
PreparedStatement ps2 = con.prepareStatement("DELETE FROM nxcode_items WHERE codeid = ?");
|
||||||
|
while (rs.next()) {
|
||||||
|
ps2.setInt(1, rs.getInt("id"));
|
||||||
|
ps2.addBatch();
|
||||||
|
}
|
||||||
|
ps2.executeBatch();
|
||||||
|
ps2.close();
|
||||||
|
|
||||||
|
ps2 = con.prepareStatement("DELETE FROM nxcode WHERE expiration <= ?");
|
||||||
|
ps2.setLong(1, timeClear);
|
||||||
|
ps2.executeUpdate();
|
||||||
|
ps2.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
}
|
||||||
|
|
||||||
private void loadCouponRates(Connection c) throws SQLException {
|
private void loadCouponRates(Connection c) throws SQLException {
|
||||||
PreparedStatement ps = c.prepareStatement("SELECT couponid, rate FROM nxcoupons");
|
PreparedStatement ps = c.prepareStatement("SELECT couponid, rate FROM nxcoupons");
|
||||||
ResultSet rs = ps.executeQuery();
|
ResultSet rs = ps.executeQuery();
|
||||||
@@ -818,6 +846,7 @@ public class Server {
|
|||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
ps.close();
|
ps.close();
|
||||||
|
|
||||||
|
cleanNxcodeCoupons(c);
|
||||||
loadCouponRates(c);
|
loadCouponRates(c);
|
||||||
updateActiveCoupons();
|
updateActiveCoupons();
|
||||||
|
|
||||||
@@ -825,6 +854,9 @@ public class Server {
|
|||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
sqle.printStackTrace();
|
sqle.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapleCashidGenerator.loadExistentCashIdsFromDb();
|
||||||
|
|
||||||
IoBuffer.setUseDirectBuffer(false);
|
IoBuffer.setUseDirectBuffer(false);
|
||||||
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
||||||
acceptor = new NioSocketAcceptor();
|
acceptor = new NioSocketAcceptor();
|
||||||
@@ -893,17 +925,6 @@ public class Server {
|
|||||||
online = true;
|
online = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown() {
|
|
||||||
try {
|
|
||||||
TimerManager.getInstance().stop();
|
|
||||||
acceptor.unbind();
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
FilePrinter.printError(FilePrinter.EXCEPTION_CAUGHT, e);
|
|
||||||
}
|
|
||||||
System.out.println("Server offline.");
|
|
||||||
System.exit(0);// BOEIEND :D
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.setProperty("wzpath", "wz");
|
System.setProperty("wzpath", "wz");
|
||||||
Security.setProperty("crypto.policy", "unlimited");
|
Security.setProperty("crypto.policy", "unlimited");
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ public final class Channel {
|
|||||||
System.out.println("Shutting down Channel " + channel + " on World " + world);
|
System.out.println("Shutting down Channel " + channel + " on World " + world);
|
||||||
|
|
||||||
closeAllMerchants();
|
closeAllMerchants();
|
||||||
|
disconnectAwayPlayers();
|
||||||
players.disconnectAll();
|
players.disconnectAll();
|
||||||
|
|
||||||
if(respawnTask != null) {
|
if(respawnTask != null) {
|
||||||
@@ -314,6 +315,10 @@ public final class Channel {
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public World getWorldServer() {
|
||||||
|
return Server.getInstance().getWorld(world);
|
||||||
|
}
|
||||||
|
|
||||||
public void addPlayer(MapleCharacter chr) {
|
public void addPlayer(MapleCharacter chr) {
|
||||||
players.addPlayer(chr);
|
players.addPlayer(chr);
|
||||||
chr.announce(MaplePacketCreator.serverMessage(serverMessage));
|
chr.announce(MaplePacketCreator.serverMessage(serverMessage));
|
||||||
@@ -394,6 +399,16 @@ public final class Channel {
|
|||||||
return players.getSize() == 0 && playersAway.isEmpty();
|
return players.getSize() == 0 && playersAway.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void disconnectAwayPlayers() {
|
||||||
|
World wserv = getWorldServer();
|
||||||
|
for (Integer cid : playersAway) {
|
||||||
|
MapleCharacter chr = wserv.getPlayerStorage().getCharacterById(cid);
|
||||||
|
if (chr != null && chr.isLoggedin()) {
|
||||||
|
chr.getClient().disconnect(true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class respawnMaps implements Runnable {
|
public class respawnMaps implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -465,7 +480,7 @@ public final class Channel {
|
|||||||
public void setServerMessage(String message) {
|
public void setServerMessage(String message) {
|
||||||
this.serverMessage = message;
|
this.serverMessage = message;
|
||||||
broadcastPacket(MaplePacketCreator.serverMessage(message));
|
broadcastPacket(MaplePacketCreator.serverMessage(message));
|
||||||
Server.getInstance().getWorld(world).resetDisabledServerMessages();
|
getWorldServer().resetDisabledServerMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String [] getEvents(){
|
private static String [] getEvents(){
|
||||||
@@ -692,7 +707,7 @@ public final class Channel {
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
World wserv = Server.getInstance().getWorld(world);
|
World wserv = getWorldServer();
|
||||||
|
|
||||||
Pair<Integer, Integer> coupleId = wserv.getMarriageQueuedCouple(ret);
|
Pair<Integer, Integer> coupleId = wserv.getMarriageQueuedCouple(ret);
|
||||||
Pair<Boolean, Set<Integer>> typeGuests = wserv.removeMarriageQueued(ret);
|
Pair<Boolean, Set<Integer>> typeGuests = wserv.removeMarriageQueued(ret);
|
||||||
@@ -704,7 +719,7 @@ public final class Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isWeddingReserved(Integer weddingId) {
|
public boolean isWeddingReserved(Integer weddingId) {
|
||||||
World wserv = Server.getInstance().getWorld(world);
|
World wserv = getWorldServer();
|
||||||
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
@@ -746,7 +761,7 @@ public final class Channel {
|
|||||||
public int pushWeddingReservation(Integer weddingId, boolean cathedral, boolean premium, Integer groomId, Integer brideId) {
|
public int pushWeddingReservation(Integer weddingId, boolean cathedral, boolean premium, Integer groomId, Integer brideId) {
|
||||||
if(weddingId == null || isWeddingReserved(weddingId)) return -1;
|
if(weddingId == null || isWeddingReserved(weddingId)) return -1;
|
||||||
|
|
||||||
World wserv = Server.getInstance().getWorld(world);
|
World wserv = getWorldServer();
|
||||||
wserv.putMarriageQueued(weddingId, cathedral, premium, groomId, brideId);
|
wserv.putMarriageQueued(weddingId, cathedral, premium, groomId, brideId);
|
||||||
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
@@ -935,7 +950,7 @@ public final class Channel {
|
|||||||
public Pair<Integer, Integer> getWeddingCoupleForGuest(int guestId, boolean cathedral) {
|
public Pair<Integer, Integer> getWeddingCoupleForGuest(int guestId, boolean cathedral) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
return (isOngoingWeddingGuest(cathedral, guestId)) ? Server.getInstance().getWorld(world).getRelationshipCouple(getOngoingWedding(cathedral)) : null;
|
return (isOngoingWeddingGuest(cathedral, guestId)) ? getWorldServer().getRelationshipCouple(getOngoingWedding(cathedral)) : null;
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
@@ -1038,7 +1053,7 @@ public final class Channel {
|
|||||||
|
|
||||||
public void debugMarriageStatus() {
|
public void debugMarriageStatus() {
|
||||||
System.out.println(" ----- WORLD DATA -----");
|
System.out.println(" ----- WORLD DATA -----");
|
||||||
Server.getInstance().getWorld(world).debugMarriageStatus();
|
getWorldServer().debugMarriageStatus();
|
||||||
|
|
||||||
System.out.println(" ----- CH. " + channel + " -----");
|
System.out.println(" ----- CH. " + channel + " -----");
|
||||||
System.out.println(" ----- CATHEDRAL -----");
|
System.out.println(" ----- CATHEDRAL -----");
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ package net.server.channel.handlers;
|
|||||||
import client.MapleClient;
|
import client.MapleClient;
|
||||||
import client.MapleCharacter;
|
import client.MapleCharacter;
|
||||||
import net.AbstractMaplePacketHandler;
|
import net.AbstractMaplePacketHandler;
|
||||||
import tools.MaplePacketCreator;
|
|
||||||
import tools.data.input.SeekableLittleEndianAccessor;
|
import tools.data.input.SeekableLittleEndianAccessor;
|
||||||
|
|
||||||
public final class CancelChairHandler extends AbstractMaplePacketHandler {
|
public final class CancelChairHandler extends AbstractMaplePacketHandler {
|
||||||
@@ -35,21 +34,6 @@ public final class CancelChairHandler extends AbstractMaplePacketHandler {
|
|||||||
MapleCharacter mc = c.getPlayer();
|
MapleCharacter mc = c.getPlayer();
|
||||||
if(!mc.isLoggedinWorld()) return;
|
if(!mc.isLoggedinWorld()) return;
|
||||||
|
|
||||||
if (id == -1) { // Cancel Chair
|
mc.sitChair(id == -1 ? 0 : id);
|
||||||
mc.setChair(0);
|
|
||||||
if(mc.unregisterChairBuff()) {
|
|
||||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.cancelForeignChairSkillEffect(mc.getId()), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
c.announce(MaplePacketCreator.cancelChair(-1));
|
|
||||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showChair(c.getPlayer().getId(), 0), false);
|
|
||||||
} else { // Use In-Map Chair
|
|
||||||
mc.setChair(id);
|
|
||||||
if(mc.registerChairBuff()) {
|
|
||||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.giveForeignChairSkillEffect(mc.getId()), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
c.announce(MaplePacketCreator.cancelChair(id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ import server.CashShop;
|
|||||||
import server.CashShop.CashItem;
|
import server.CashShop.CashItem;
|
||||||
import server.CashShop.CashItemFactory;
|
import server.CashShop.CashItemFactory;
|
||||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||||
|
import constants.ServerConstants;
|
||||||
import tools.FilePrinter;
|
import tools.FilePrinter;
|
||||||
import tools.MaplePacketCreator;
|
import tools.MaplePacketCreator;
|
||||||
|
import tools.Pair;
|
||||||
import tools.data.input.SeekableLittleEndianAccessor;
|
import tools.data.input.SeekableLittleEndianAccessor;
|
||||||
|
|
||||||
public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
||||||
@@ -62,18 +64,20 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
CashItem cItem = CashItemFactory.getItem(snCS);
|
CashItem cItem = CashItemFactory.getItem(snCS);
|
||||||
if (!canBuy(cItem, cs.getCash(useNX))) {
|
if (!canBuy(cItem, cs.getCash(useNX))) {
|
||||||
FilePrinter.printError(FilePrinter.ITEM, "Denied to sell cash item with SN " + cItem.getSN());
|
FilePrinter.printError(FilePrinter.ITEM, "Denied to sell cash item with SN " + cItem.getSN());
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ItemConstants.isCashStore(cItem.getItemId()) && chr.getLevel() < 16) {
|
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == 0x03) { // Item
|
if (action == 0x03) { // Item
|
||||||
if(ItemConstants.isMapleLife(cItem.getItemId()) && chr.getLevel() < 30) {
|
if (ItemConstants.isCashStore(cItem.getItemId()) && chr.getLevel() < 16) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
|
return;
|
||||||
|
} else if (ItemConstants.isRateCoupon(cItem.getItemId()) && !ServerConstants.USE_SUPPLY_RATE_COUPONS) {
|
||||||
|
chr.dropMessage(1, "Rate coupons are currently unavailable to purchase.");
|
||||||
|
c.enableCSActions();
|
||||||
|
return;
|
||||||
|
} else if (ItemConstants.isMapleLife(cItem.getItemId()) && chr.getLevel() < 30) {
|
||||||
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,20 +99,17 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
Map<String, String> recipient = MapleCharacter.getCharacterFromDatabase(slea.readMapleAsciiString());
|
Map<String, String> recipient = MapleCharacter.getCharacterFromDatabase(slea.readMapleAsciiString());
|
||||||
String message = slea.readMapleAsciiString();
|
String message = slea.readMapleAsciiString();
|
||||||
if (!canBuy(cItem, cs.getCash(4)) || message.length() < 1 || message.length() > 73) {
|
if (!canBuy(cItem, cs.getCash(4)) || message.length() < 1 || message.length() > 73) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!checkBirthday(c, birthday)) {
|
if (!checkBirthday(c, birthday)) {
|
||||||
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
|
||||||
return;
|
return;
|
||||||
} else if (recipient == null) {
|
} else if (recipient == null) {
|
||||||
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xA9));
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xA9));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
|
||||||
return;
|
return;
|
||||||
} else if (recipient.get("accountid").equals(String.valueOf(c.getAccID()))) {
|
} else if (recipient.get("accountid").equals(String.valueOf(c.getAccID()))) {
|
||||||
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xA8));
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xA8));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cs.gift(Integer.parseInt(recipient.get("id")), chr.getName(), message, cItem.getSN());
|
cs.gift(Integer.parseInt(recipient.get("id")), chr.getName(), message, cItem.getSN());
|
||||||
@@ -139,7 +140,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
if (mode == 0) {
|
if (mode == 0) {
|
||||||
byte type = slea.readByte();
|
byte type = slea.readByte();
|
||||||
if (cs.getCash(cash) < 4000) {
|
if (cs.getCash(cash) < 4000) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (chr.gainSlots(type, 4, false)) {
|
if (chr.gainSlots(type, 4, false)) {
|
||||||
@@ -151,7 +152,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
CashItem cItem = CashItemFactory.getItem(slea.readInt());
|
CashItem cItem = CashItemFactory.getItem(slea.readInt());
|
||||||
int type = (cItem.getItemId() - 9110000) / 1000;
|
int type = (cItem.getItemId() - 9110000) / 1000;
|
||||||
if (!canBuy(cItem, cs.getCash(cash))) {
|
if (!canBuy(cItem, cs.getCash(cash))) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (chr.gainSlots(type, 8, false)) {
|
if (chr.gainSlots(type, 8, false)) {
|
||||||
@@ -166,7 +167,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
byte mode = slea.readByte();
|
byte mode = slea.readByte();
|
||||||
if (mode == 0) {
|
if (mode == 0) {
|
||||||
if (cs.getCash(cash) < 4000) {
|
if (cs.getCash(cash) < 4000) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (chr.getStorage().gainSlots(4)) {
|
if (chr.getStorage().gainSlots(4)) {
|
||||||
@@ -181,7 +182,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
CashItem cItem = CashItemFactory.getItem(slea.readInt());
|
CashItem cItem = CashItemFactory.getItem(slea.readInt());
|
||||||
|
|
||||||
if (!canBuy(cItem, cs.getCash(cash))) {
|
if (!canBuy(cItem, cs.getCash(cash))) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (chr.getStorage().gainSlots(8)) {
|
if (chr.getStorage().gainSlots(8)) {
|
||||||
@@ -196,7 +197,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
CashItem cItem = CashItemFactory.getItem(slea.readInt());
|
CashItem cItem = CashItemFactory.getItem(slea.readInt());
|
||||||
|
|
||||||
if (!canBuy(cItem, cs.getCash(cash))) {
|
if (!canBuy(cItem, cs.getCash(cash))) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,13 +207,13 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
c.announce(MaplePacketCreator.showCash(chr));
|
c.announce(MaplePacketCreator.showCash(chr));
|
||||||
} else {
|
} else {
|
||||||
chr.dropMessage(1, "You have already used up all 12 extra character slots.");
|
chr.dropMessage(1, "You have already used up all 12 extra character slots.");
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (action == 0x0D) { // Take from Cash Inventory
|
} else if (action == 0x0D) { // Take from Cash Inventory
|
||||||
Item item = cs.findByCashId(slea.readInt());
|
Item item = cs.findByCashId(slea.readInt());
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (chr.getInventory(item.getInventoryType()).addItem(item) != -1) {
|
if (chr.getInventory(item.getInventoryType()).addItem(item) != -1) {
|
||||||
@@ -240,11 +241,11 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
MapleInventory mi = chr.getInventory(MapleInventoryType.getByType(invType));
|
MapleInventory mi = chr.getInventory(MapleInventoryType.getByType(invType));
|
||||||
Item item = mi.findByCashId(cashId);
|
Item item = mi.findByCashId(cashId);
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
} else if(c.getPlayer().getPetIndex(item.getPetId()) > -1) {
|
} else if(c.getPlayer().getPetIndex(item.getPetId()) > -1) {
|
||||||
chr.getClient().announce(MaplePacketCreator.serverNotice(1, "You cannot put the pet you currently equip into the Cash Shop inventory."));
|
chr.getClient().announce(MaplePacketCreator.serverNotice(1, "You cannot put the pet you currently equip into the Cash Shop inventory."));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cs.addToInventory(item);
|
cs.addToInventory(item);
|
||||||
@@ -265,19 +266,19 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
|
|
||||||
/* if (partner.getGender() == chr.getGender()) {
|
/* if (partner.getGender() == chr.getGender()) {
|
||||||
chr.dropMessage("You and your partner are the same gender, please buy a friendship ring.");
|
chr.dropMessage("You and your partner are the same gender, please buy a friendship ring.");
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}*/ //Gotta let them faggots marry too, hence why this is commented out <3
|
}*/ //Gotta let them faggots marry too, hence why this is commented out <3
|
||||||
|
|
||||||
if(itemRing.toItem() instanceof Equip) {
|
if(itemRing.toItem() instanceof Equip) {
|
||||||
Equip eqp = (Equip) itemRing.toItem();
|
Equip eqp = (Equip) itemRing.toItem();
|
||||||
int ringid = MapleRing.createRing(itemRing.getItemId(), chr, partner);
|
Pair<Integer, Integer> rings = MapleRing.createRing(itemRing.getItemId(), chr, partner);
|
||||||
eqp.setRingId(ringid);
|
eqp.setRingId(rings.getLeft());
|
||||||
cs.addToInventory(eqp);
|
cs.addToInventory(eqp);
|
||||||
c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
|
c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
|
||||||
cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), (ringid + 1));
|
cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), rings.getRight());
|
||||||
cs.gainCash(toCharge, itemRing, chr.getWorld());
|
cs.gainCash(toCharge, itemRing, chr.getWorld());
|
||||||
chr.addCrushRing(MapleRing.loadFromDb(ringid));
|
chr.addCrushRing(MapleRing.loadFromDb(rings.getLeft()));
|
||||||
try {
|
try {
|
||||||
chr.sendNote(partner.getName(), text, (byte) 1);
|
chr.sendNote(partner.getName(), text, (byte) 1);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
@@ -288,17 +289,33 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
|
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
|
||||||
} else if (action == 0x20) { // everything is 1 meso...
|
} else if (action == 0x20) {
|
||||||
int itemId = CashItemFactory.getItem(slea.readInt()).getItemId();
|
int serialNumber = slea.readInt(); // thanks GabrielSin for detecting a potential exploit with 1 meso cash items.
|
||||||
|
if (serialNumber / 10000000 != 8) {
|
||||||
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (chr.getMeso() > 0) {
|
CashItem item = CashItemFactory.getItem(serialNumber);
|
||||||
|
if (item == null || !item.isOnSale()) {
|
||||||
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int itemId = item.getItemId();
|
||||||
|
int itemPrice = item.getPrice();
|
||||||
|
if (itemPrice <= 0) {
|
||||||
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chr.getMeso() >= itemPrice) {
|
||||||
if (chr.canHold(itemId)) {
|
if (chr.canHold(itemId)) {
|
||||||
chr.gainMeso(-1, false);
|
chr.gainMeso(-itemPrice, false);
|
||||||
MapleInventoryManipulator.addById(c, itemId, (short) 1);
|
MapleInventoryManipulator.addById(c, itemId, (short) 1, "", -1);
|
||||||
c.announce(MaplePacketCreator.showBoughtQuestItem(itemId));
|
c.announce(MaplePacketCreator.showBoughtQuestItem(itemId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,13 +338,13 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
// Need to check to make sure its actually an equip and the right SN...
|
// Need to check to make sure its actually an equip and the right SN...
|
||||||
if(itemRing.toItem() instanceof Equip) {
|
if(itemRing.toItem() instanceof Equip) {
|
||||||
Equip eqp = (Equip) itemRing.toItem();
|
Equip eqp = (Equip) itemRing.toItem();
|
||||||
int ringid = MapleRing.createRing(itemRing.getItemId(), chr, partner);
|
Pair<Integer, Integer> rings = MapleRing.createRing(itemRing.getItemId(), chr, partner);
|
||||||
eqp.setRingId(ringid);
|
eqp.setRingId(rings.getLeft());
|
||||||
cs.addToInventory(eqp);
|
cs.addToInventory(eqp);
|
||||||
c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
|
c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
|
||||||
cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), (ringid + 1));
|
cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), rings.getRight());
|
||||||
cs.gainCash(payment, -itemRing.getPrice());
|
cs.gainCash(payment, -itemRing.getPrice());
|
||||||
chr.addFriendshipRing(MapleRing.loadFromDb(ringid));
|
chr.addFriendshipRing(MapleRing.loadFromDb(rings.getLeft()));
|
||||||
try {
|
try {
|
||||||
chr.sendNote(partner.getName(), text, (byte) 1);
|
chr.sendNote(partner.getName(), text, (byte) 1);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
@@ -338,7 +355,6 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
|
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
|||||||
@Override
|
@Override
|
||||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
MapleCharacter chr = c.getPlayer();
|
MapleCharacter chr = c.getPlayer();
|
||||||
chr.setPetLootCd(currentServerTime());
|
//chr.setPetLootCd(currentServerTime());
|
||||||
|
|
||||||
/*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8);
|
/*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8);
|
||||||
if(timeElapsed < 300) {
|
if(timeElapsed < 300) {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
Matthias Butz <matze@odinms.de>
|
Matthias Butz <matze@odinms.de>
|
||||||
Jan Christian Meyer <vimes@odinms.de>
|
Jan Christian Meyer <vimes@odinms.de>
|
||||||
|
|
||||||
|
Copyleft (L) 2016 - 2018 RonanLana (HeavenMS)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as
|
||||||
published by the Free Software Foundation version 3 as published by
|
published by the Free Software Foundation version 3 as published by
|
||||||
@@ -21,107 +23,228 @@
|
|||||||
*/
|
*/
|
||||||
package net.server.channel.handlers;
|
package net.server.channel.handlers;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import client.MapleClient;
|
import client.MapleClient;
|
||||||
|
import client.MapleCharacter;
|
||||||
|
import client.inventory.Item;
|
||||||
|
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import net.AbstractMaplePacketHandler;
|
import net.AbstractMaplePacketHandler;
|
||||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
import net.server.Server;
|
||||||
|
import server.CashShop;
|
||||||
|
import server.MapleItemInformationProvider;
|
||||||
import tools.DatabaseConnection;
|
import tools.DatabaseConnection;
|
||||||
|
import tools.FilePrinter;
|
||||||
import tools.MaplePacketCreator;
|
import tools.MaplePacketCreator;
|
||||||
|
import tools.Pair;
|
||||||
import tools.data.input.SeekableLittleEndianAccessor;
|
import tools.data.input.SeekableLittleEndianAccessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Penguins (Acrylic)
|
* @author Penguins (Acrylic)
|
||||||
|
* @author Ronan (HeavenMS)
|
||||||
*/
|
*/
|
||||||
public final class CouponCodeHandler extends AbstractMaplePacketHandler {
|
public final class CouponCodeHandler extends AbstractMaplePacketHandler {
|
||||||
|
|
||||||
|
private static List<Pair<Integer, Pair<Integer, Integer>>> getNXCodeItems(MapleCharacter chr, Connection con, int codeid) throws SQLException {
|
||||||
|
Map<Integer, Integer> couponItems = new HashMap<>();
|
||||||
|
Map<Integer, Integer> couponPoints = new HashMap<>(5);
|
||||||
|
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT * FROM nxcode_items WHERE codeid = ?");
|
||||||
|
ps.setInt(1, codeid);
|
||||||
|
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
int type = rs.getInt("type"), item = rs.getInt("item");
|
||||||
|
|
||||||
|
if (type < 5) {
|
||||||
|
Integer i = couponPoints.get(type);
|
||||||
|
if (i != null) {
|
||||||
|
couponPoints.put(type, i + item);
|
||||||
|
} else {
|
||||||
|
couponPoints.put(type, item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int quantity = rs.getInt("quantity");
|
||||||
|
|
||||||
|
Integer i = couponItems.get(item);
|
||||||
|
if (i != null) {
|
||||||
|
couponItems.put(item, i + quantity);
|
||||||
|
} else {
|
||||||
|
couponItems.put(item, quantity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
|
||||||
|
List<Pair<Integer, Pair<Integer, Integer>>> ret = new LinkedList<>();
|
||||||
|
if (!couponItems.isEmpty()) {
|
||||||
|
for (Entry<Integer, Integer> e : couponItems.entrySet()) {
|
||||||
|
int item = e.getKey(), qty = e.getValue();
|
||||||
|
|
||||||
|
if (MapleItemInformationProvider.getInstance().getName(item) == null) {
|
||||||
|
item = 4000000;
|
||||||
|
qty = 1;
|
||||||
|
|
||||||
|
FilePrinter.printError(FilePrinter.UNHANDLED_EVENT, "Error trying to redeem itemid " + item + " from codeid " + codeid + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chr.canHold(item, qty)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.add(new Pair<>(5, new Pair<>(item, qty)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!couponPoints.isEmpty()) {
|
||||||
|
for (Entry<Integer, Integer> e : couponPoints.entrySet()) {
|
||||||
|
ret.add(new Pair<>(e.getKey(), new Pair<>(e.getValue(), 777)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pair<Integer, List<Pair<Integer, Pair<Integer, Integer>>>> getNXCodeResult(MapleCharacter chr, String code) {
|
||||||
|
MapleClient c = chr.getClient();
|
||||||
|
List<Pair<Integer, Pair<Integer, Integer>>> ret = new LinkedList<>();
|
||||||
|
try {
|
||||||
|
if (!c.attemptCsCoupon()) {
|
||||||
|
return new Pair<>(-5, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection con = DatabaseConnection.getConnection();
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT * FROM nxcode WHERE code = ?");
|
||||||
|
ps.setString(1, code);
|
||||||
|
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (!rs.next()) {
|
||||||
|
return new Pair<>(-1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rs.getString("retriever") != null) {
|
||||||
|
return new Pair<>(-2, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rs.getLong("expiration") < Server.getInstance().getCurrentTime()) {
|
||||||
|
return new Pair<>(-3, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
int codeid = rs.getInt("id");
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
|
||||||
|
ret = getNXCodeItems(chr, con, codeid);
|
||||||
|
if (ret == null) {
|
||||||
|
return new Pair<>(-4, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ps = con.prepareStatement("UPDATE nxcode SET retriever = ? WHERE code = ?");
|
||||||
|
ps.setString(1, chr.getName());
|
||||||
|
ps.setString(2, code);
|
||||||
|
ps.executeUpdate();
|
||||||
|
|
||||||
|
ps.close();
|
||||||
|
con.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
c.resetCsCoupon();
|
||||||
|
return new Pair<>(0, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int parseCouponResult(int res) {
|
||||||
|
switch (res) {
|
||||||
|
case -1:
|
||||||
|
return 0xB0;
|
||||||
|
|
||||||
|
case -2:
|
||||||
|
return 0xB3;
|
||||||
|
|
||||||
|
case -3:
|
||||||
|
return 0xB2;
|
||||||
|
|
||||||
|
case -4:
|
||||||
|
return 0xBB;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0xB1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
slea.skip(2);
|
slea.skip(2);
|
||||||
String code = slea.readMapleAsciiString();
|
String code = slea.readMapleAsciiString();
|
||||||
boolean validcode = false;
|
|
||||||
int type = -1;
|
if (c.tryacquireClient()) {
|
||||||
int item = -1;
|
|
||||||
validcode = getNXCodeValid(code.toUpperCase(), validcode);
|
|
||||||
if (validcode) {
|
|
||||||
type = getNXCode(code, "type");
|
|
||||||
item = getNXCode(code, "item");
|
|
||||||
if (type != 5) {
|
|
||||||
try {
|
try {
|
||||||
Connection con = DatabaseConnection.getConnection();
|
Pair<Integer, List<Pair<Integer, Pair<Integer, Integer>>>> codeRes = getNXCodeResult(c.getPlayer(), code.toUpperCase());
|
||||||
PreparedStatement ps = con.prepareStatement("UPDATE nxcode SET `valid` = 0 WHERE code = " + code);
|
int type = codeRes.getLeft();
|
||||||
ps.executeUpdate();
|
if (type < 0) {
|
||||||
ps.close();
|
c.announce(MaplePacketCreator.showCashShopMessage((byte) parseCouponResult(type)));
|
||||||
ps = con.prepareStatement("UPDATE nxcode SET `user` = ? WHERE code = ?");
|
} else {
|
||||||
ps.setString(1, c.getPlayer().getName());
|
List<Item> couponPackage = new LinkedList<>();
|
||||||
ps.setString(2, code);
|
|
||||||
ps.executeUpdate();
|
for (Pair<Integer, Pair<Integer, Integer>> p : codeRes.getRight()) {
|
||||||
ps.close();
|
type = p.getLeft();
|
||||||
con.close();
|
int item = p.getRight().getLeft();
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
CashShop cs = c.getPlayer().getCashShop();
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
|
case 4:
|
||||||
|
cs.gainCash(1, item); //nxCredit
|
||||||
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
cs.gainCash(2, item); //maplePoint
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
c.getPlayer().getCashShop().gainCash(type, item);
|
cs.gainCash(4, item); //nxPrepaid
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
c.getPlayer().getCashShop().gainCash(0, item);
|
cs.gainCash(1, item);
|
||||||
c.getPlayer().getCashShop().gainCash(2, (item / 5000));
|
cs.gainCash(4, (item / 5000));
|
||||||
break;
|
break;
|
||||||
case 4:
|
|
||||||
MapleInventoryManipulator.addById(c, item, (short) 1, null, -1, -1);
|
default:
|
||||||
c.announce(MaplePacketCreator.showCouponRedeemedItem(item));
|
short qty = p.getRight().getRight().shortValue();
|
||||||
break;
|
if (MapleItemInformationProvider.getInstance().isCash(item)) {
|
||||||
case 5:
|
Item it = CashShop.generateCouponItem(item, qty);
|
||||||
c.getPlayer().getCashShop().gainCash(0, item);
|
|
||||||
break;
|
cs.addToInventory(it);
|
||||||
}
|
couponPackage.add(it);
|
||||||
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
|
|
||||||
} else {
|
} else {
|
||||||
//c.announce(MaplePacketCreator.wrongCouponCode());
|
MapleInventoryManipulator.addById(c, item, qty, "", -1);
|
||||||
}
|
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getNXCode(String code, String type) {
|
//c.announce(MaplePacketCreator.showCouponRedeemedItem(item));
|
||||||
int item = -1;
|
break;
|
||||||
try {
|
|
||||||
Connection con = DatabaseConnection.getConnection();
|
|
||||||
PreparedStatement ps = con.prepareStatement("SELECT `" + type + "` FROM nxcode WHERE code = ?");
|
|
||||||
ps.setString(1, code);
|
|
||||||
ResultSet rs = ps.executeQuery();
|
|
||||||
while (rs.next()) {
|
|
||||||
item = rs.getInt(type);
|
|
||||||
}
|
}
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
con.close();
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getNXCodeValid(String code, boolean validcode) {
|
if (!couponPackage.isEmpty()) {
|
||||||
try {
|
c.announce(MaplePacketCreator.showBoughtCashPackage(couponPackage, c.getAccID()));
|
||||||
Connection con = DatabaseConnection.getConnection();
|
} else {
|
||||||
PreparedStatement ps = con.prepareStatement("SELECT `valid` FROM nxcode WHERE code = ?");
|
c.announce(MaplePacketCreator.showBoughtQuestItem(0));
|
||||||
ps.setString(1, code);
|
}
|
||||||
ResultSet rs = ps.executeQuery();
|
|
||||||
while (rs.next()) {
|
c.enableCSActions();
|
||||||
validcode = rs.getInt("valid") != 0;
|
}
|
||||||
|
} finally {
|
||||||
|
c.releaseClient();
|
||||||
}
|
}
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
con.close();
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return validcode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
|||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
chr.getCashShop().open(true);// xD
|
chr.getCashShop().open(true);// xD
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(MaplePacketCreator.MTSWantedListingOver(0, 0));
|
c.announce(MaplePacketCreator.MTSWantedListingOver(0, 0));
|
||||||
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
||||||
List<MTSItemInfo> items = new ArrayList<>();
|
List<MTSItemInfo> items = new ArrayList<>();
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ public final class FaceExpressionHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(c.trylockClient()) {
|
if(c.tryacquireClient()) {
|
||||||
try { // expecting players never intends to wear the emote 0 (default face, that changes back after 5sec timeout)
|
try { // expecting players never intends to wear the emote 0 (default face, that changes back after 5sec timeout)
|
||||||
if (emote != 0 && chr.isLoggedinWorld()) {
|
if (emote != 0 && chr.isLoggedinWorld()) {
|
||||||
chr.changeFaceExpression(emote);
|
chr.changeFaceExpression(emote);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
c.releaseClient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public final class ItemRewardHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
MapleInventoryManipulator.addFromDrop(c, item, false);
|
MapleInventoryManipulator.addFromDrop(c, item, false);
|
||||||
} else {
|
} else {
|
||||||
MapleInventoryManipulator.addById(c, reward.itemid, reward.quantity);
|
MapleInventoryManipulator.addById(c, reward.itemid, reward.quantity, "", -1);
|
||||||
}
|
}
|
||||||
MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemId, 1, false, false);
|
MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemId, 1, false, false);
|
||||||
if (reward.worldmsg != null) {
|
if (reward.worldmsg != null) {
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
c.getPlayer().gainMeso(-5000, false);
|
c.getPlayer().gainMeso(-5000, false);
|
||||||
c.announce(MaplePacketCreator.MTSConfirmSell());
|
c.announce(MaplePacketCreator.MTSConfirmSell());
|
||||||
c.announce(getMTS(1, 0, 0));
|
c.announce(getMTS(1, 0, 0));
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
||||||
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
||||||
}
|
}
|
||||||
@@ -240,7 +240,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
c.getPlayer().changeTab(tab);
|
c.getPlayer().changeTab(tab);
|
||||||
c.getPlayer().changeType(type);
|
c.getPlayer().changeType(type);
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
||||||
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
||||||
} else if (op == 6) { //search
|
} else if (op == 6) { //search
|
||||||
@@ -253,7 +253,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
c.getPlayer().changeTab(tab);
|
c.getPlayer().changeTab(tab);
|
||||||
c.getPlayer().changeType(type);
|
c.getPlayer().changeType(type);
|
||||||
c.getPlayer().changeCI(ci);
|
c.getPlayer().changeCI(ci);
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
c.announce(getMTSSearch(tab, type, ci, search, c.getPlayer().getCurrentPage()));
|
c.announce(getMTSSearch(tab, type, ci, search, c.getPlayer().getCurrentPage()));
|
||||||
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
||||||
@@ -277,7 +277,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
||||||
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
||||||
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
||||||
@@ -331,7 +331,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
pse.executeUpdate();
|
pse.executeUpdate();
|
||||||
}
|
}
|
||||||
MapleInventoryManipulator.addFromDrop(c, i, false);
|
MapleInventoryManipulator.addFromDrop(c, i, false);
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(getCart(c.getPlayer().getId()));
|
c.announce(getCart(c.getPlayer().getId()));
|
||||||
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
||||||
c.announce(MaplePacketCreator.MTSConfirmTransfer(i.getQuantity(), i.getPosition()));
|
c.announce(MaplePacketCreator.MTSConfirmTransfer(i.getQuantity(), i.getPosition()));
|
||||||
@@ -374,7 +374,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
||||||
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
||||||
@@ -393,7 +393,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
c.announce(getCart(c.getPlayer().getId()));
|
c.announce(getCart(c.getPlayer().getId()));
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
||||||
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(c.getPlayer().getId())));
|
||||||
} else if (op == 12) { //put item up for auction
|
} else if (op == 12) { //put item up for auction
|
||||||
@@ -445,7 +445,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
pse.executeUpdate();
|
pse.executeUpdate();
|
||||||
pse.close();
|
pse.close();
|
||||||
c.getPlayer().getCashShop().gainCash(4, -price);
|
c.getPlayer().getCashShop().gainCash(4, -price);
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
c.announce(getMTS(c.getPlayer().getCurrentTab(), c.getPlayer().getCurrentType(), c.getPlayer().getCurrentPage()));
|
||||||
c.announce(MaplePacketCreator.MTSConfirmBuy());
|
c.announce(MaplePacketCreator.MTSConfirmBuy());
|
||||||
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
||||||
@@ -507,7 +507,7 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
|||||||
pse.close();
|
pse.close();
|
||||||
c.getPlayer().getCashShop().gainCash(4, -price);
|
c.getPlayer().getCashShop().gainCash(4, -price);
|
||||||
c.announce(getCart(c.getPlayer().getId()));
|
c.announce(getCart(c.getPlayer().getId()));
|
||||||
c.announce(MaplePacketCreator.enableCSUse());
|
c.enableCSActions();
|
||||||
c.announce(MaplePacketCreator.MTSConfirmBuy());
|
c.announce(MaplePacketCreator.MTSConfirmBuy());
|
||||||
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
|
||||||
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
c.announce(MaplePacketCreator.transferInventory(getTransfer(c.getPlayer().getId())));
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
|||||||
@Override
|
@Override
|
||||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
MapleCharacter chr = c.getPlayer();
|
MapleCharacter chr = c.getPlayer();
|
||||||
chr.setPetLootCd(currentServerTime());
|
//chr.setPetLootCd(currentServerTime());
|
||||||
|
|
||||||
/*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8);
|
/*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8);
|
||||||
if(timeElapsed < 300) {
|
if(timeElapsed < 300) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ package net.server.channel.handlers;
|
|||||||
|
|
||||||
import client.MapleCharacter;
|
import client.MapleCharacter;
|
||||||
import client.MapleClient;
|
import client.MapleClient;
|
||||||
|
import client.inventory.MapleInventory;
|
||||||
import client.inventory.MapleInventoryType;
|
import client.inventory.MapleInventoryType;
|
||||||
import client.inventory.MaplePet;
|
import client.inventory.MaplePet;
|
||||||
import client.autoban.AutobanManager;
|
import client.autoban.AutobanManager;
|
||||||
@@ -65,18 +66,25 @@ public final class PetFoodHandler extends AbstractMaplePacketHandler {
|
|||||||
|
|
||||||
short pos = slea.readShort();
|
short pos = slea.readShort();
|
||||||
int itemId = slea.readInt();
|
int itemId = slea.readInt();
|
||||||
Item use = chr.getInventory(MapleInventoryType.USE).getItem(pos);
|
|
||||||
if (use == null || (itemId / 10000) != 212 || use.getItemId() != itemId) {
|
if (c.tryacquireClient()) {
|
||||||
|
try {
|
||||||
|
MapleInventory useInv = chr.getInventory(MapleInventoryType.USE);
|
||||||
|
useInv.lockInventory();
|
||||||
|
try {
|
||||||
|
Item use = useInv.getItem(pos);
|
||||||
|
if (use == null || (itemId / 10000) != 212 || use.getItemId() != itemId || use.getQuantity() < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.lockClient();
|
|
||||||
try {
|
|
||||||
pet.gainClosenessFullness(chr, (pet.getFullness() <= 75) ? 1 : 0, 30, 1); // 25+ "emptyness" to get +1 closeness
|
pet.gainClosenessFullness(chr, (pet.getFullness() <= 75) ? 1 : 0, 30, 1); // 25+ "emptyness" to get +1 closeness
|
||||||
} finally {
|
|
||||||
c.unlockClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, pos, (short) 1, false);
|
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, pos, (short) 1, false);
|
||||||
|
} finally {
|
||||||
|
useInv.unlockInventory();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
c.releaseClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Matze
|
* @author Matze
|
||||||
|
* @author Ronan (concurrency safety & reviewed minigames)
|
||||||
*/
|
*/
|
||||||
public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||||
public enum Action {
|
public enum Action {
|
||||||
@@ -109,7 +110,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int estabilishMiniroomStatus(MapleCharacter chr, boolean isMinigame) {
|
private static int establishMiniroomStatus(MapleCharacter chr, boolean isMinigame) {
|
||||||
if (isMinigame && FieldLimit.CANNOTMINIGAME.check(chr.getMap().getFieldLimit())) {
|
if (isMinigame && FieldLimit.CANNOTMINIGAME.check(chr.getMap().getFieldLimit())) {
|
||||||
return 11;
|
return 11;
|
||||||
}
|
}
|
||||||
@@ -127,6 +128,12 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
|
if (!c.tryacquireClient()) { // thanks GabrielSin for pointing dupes within player interactions
|
||||||
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
byte mode = slea.readByte();
|
byte mode = slea.readByte();
|
||||||
final MapleCharacter chr = c.getPlayer();
|
final MapleCharacter chr = c.getPlayer();
|
||||||
|
|
||||||
@@ -140,15 +147,31 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
if (createType == 3) {// trade
|
if (createType == 3) {// trade
|
||||||
MapleTrade.startTrade(chr);
|
MapleTrade.startTrade(chr);
|
||||||
} else if (createType == 1) { // omok mini game
|
} else if (createType == 1) { // omok mini game
|
||||||
int status = estabilishMiniroomStatus(chr, true);
|
int status = establishMiniroomStatus(chr, true);
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status));
|
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String desc = slea.readMapleAsciiString();
|
String desc = slea.readMapleAsciiString();
|
||||||
|
String pw;
|
||||||
|
|
||||||
|
if (slea.readByte() != 0) {
|
||||||
|
pw = slea.readMapleAsciiString();
|
||||||
|
} else {
|
||||||
|
pw = "";
|
||||||
|
}
|
||||||
|
|
||||||
int type = slea.readByte();
|
int type = slea.readByte();
|
||||||
String pw = slea.available() > 1 ? slea.readMapleAsciiString() : "";
|
if (type > 11) {
|
||||||
|
type = 11;
|
||||||
|
} else if (type < 0) {
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
if (!chr.haveItem(4080000 + type)) {
|
||||||
|
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(6));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MapleMiniGame game = new MapleMiniGame(chr, desc, pw);
|
MapleMiniGame game = new MapleMiniGame(chr, desc, pw);
|
||||||
chr.setMiniGame(game);
|
chr.setMiniGame(game);
|
||||||
@@ -158,15 +181,31 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
chr.getMap().broadcastMessage(MaplePacketCreator.addOmokBox(chr, 1, 0));
|
chr.getMap().broadcastMessage(MaplePacketCreator.addOmokBox(chr, 1, 0));
|
||||||
game.sendOmok(c, type);
|
game.sendOmok(c, type);
|
||||||
} else if (createType == 2) { // matchcard
|
} else if (createType == 2) { // matchcard
|
||||||
int status = estabilishMiniroomStatus(chr, true);
|
int status = establishMiniroomStatus(chr, true);
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status));
|
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String desc = slea.readMapleAsciiString();
|
String desc = slea.readMapleAsciiString();
|
||||||
|
String pw;
|
||||||
|
|
||||||
|
if (slea.readByte() != 0) {
|
||||||
|
pw = slea.readMapleAsciiString();
|
||||||
|
} else {
|
||||||
|
pw = "";
|
||||||
|
}
|
||||||
|
|
||||||
int type = slea.readByte();
|
int type = slea.readByte();
|
||||||
String pw = slea.available() > 1 ? slea.readMapleAsciiString() : "";
|
if (type > 2) {
|
||||||
|
type = 2;
|
||||||
|
} else if (type < 0) {
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
if (!chr.haveItem(4080100)) {
|
||||||
|
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(6));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MapleMiniGame game = new MapleMiniGame(chr, desc, pw);
|
MapleMiniGame game = new MapleMiniGame(chr, desc, pw);
|
||||||
game.setPieceType(type);
|
game.setPieceType(type);
|
||||||
@@ -188,7 +227,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = estabilishMiniroomStatus(chr, false);
|
int status = establishMiniroomStatus(chr, false);
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status));
|
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(status));
|
||||||
return;
|
return;
|
||||||
@@ -326,46 +365,52 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
game.broadcast(MaplePacketCreator.getMiniGameUnReady(game));
|
game.broadcast(MaplePacketCreator.getMiniGameUnReady(game));
|
||||||
} else if (mode == Action.START.getCode()) {
|
} else if (mode == Action.START.getCode()) {
|
||||||
MapleMiniGame game = chr.getMiniGame();
|
MapleMiniGame game = chr.getMiniGame();
|
||||||
if (game.getGameType().equals("omok")) {
|
if (game.getGameType().equals(MiniGameType.OMOK)) {
|
||||||
|
game.minigameMatchStarted();
|
||||||
game.broadcast(MaplePacketCreator.getMiniGameStart(game, game.getLoser()));
|
game.broadcast(MaplePacketCreator.getMiniGameStart(game, game.getLoser()));
|
||||||
chr.getMap().broadcastMessage(MaplePacketCreator.addOmokBox(game.getOwner(), 2, 1));
|
chr.getMap().broadcastMessage(MaplePacketCreator.addOmokBox(game.getOwner(), 2, 1));
|
||||||
}
|
} else if (game.getGameType().equals(MiniGameType.MATCH_CARD)) {
|
||||||
if (game.getGameType().equals("matchcard")) {
|
game.minigameMatchStarted();
|
||||||
game.shuffleList();
|
game.shuffleList();
|
||||||
game.broadcast(MaplePacketCreator.getMatchCardStart(game, game.getLoser()));
|
game.broadcast(MaplePacketCreator.getMatchCardStart(game, game.getLoser()));
|
||||||
chr.getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(game.getOwner(), 2, 1));
|
chr.getMap().broadcastMessage(MaplePacketCreator.addMatchCardBox(game.getOwner(), 2, 1));
|
||||||
}
|
}
|
||||||
} else if (mode == Action.GIVE_UP.getCode()) {
|
} else if (mode == Action.GIVE_UP.getCode()) {
|
||||||
MapleMiniGame game = chr.getMiniGame();
|
MapleMiniGame game = chr.getMiniGame();
|
||||||
if (game.getGameType().equals("omok")) {
|
if (game.getGameType().equals(MiniGameType.OMOK)) {
|
||||||
if (game.isOwner(chr)) {
|
if (game.isOwner(chr)) {
|
||||||
game.broadcast(MaplePacketCreator.getMiniGameOwnerForfeit(game));
|
game.minigameMatchVisitorWins(true);
|
||||||
} else {
|
} else {
|
||||||
game.broadcast(MaplePacketCreator.getMiniGameVisitorForfeit(game));
|
game.minigameMatchOwnerWins(true);
|
||||||
}
|
}
|
||||||
}
|
} else if (game.getGameType().equals(MiniGameType.MATCH_CARD)) {
|
||||||
if (game.getGameType().equals("matchcard")) {
|
|
||||||
if (game.isOwner(chr)) {
|
if (game.isOwner(chr)) {
|
||||||
game.broadcast(MaplePacketCreator.getMatchCardVisitorWin(game));
|
game.minigameMatchVisitorWins(true);
|
||||||
} else {
|
} else {
|
||||||
game.broadcast(MaplePacketCreator.getMatchCardOwnerWin(game));
|
game.minigameMatchOwnerWins(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mode == Action.REQUEST_TIE.getCode()) {
|
} else if (mode == Action.REQUEST_TIE.getCode()) {
|
||||||
MapleMiniGame game = chr.getMiniGame();
|
MapleMiniGame game = chr.getMiniGame();
|
||||||
|
if (!game.isTieDenied(chr)) {
|
||||||
if (game.isOwner(chr)) {
|
if (game.isOwner(chr)) {
|
||||||
game.broadcastToVisitor(MaplePacketCreator.getMiniGameRequestTie(game));
|
game.broadcastToVisitor(MaplePacketCreator.getMiniGameRequestTie(game));
|
||||||
} else {
|
} else {
|
||||||
game.getOwner().getClient().announce(MaplePacketCreator.getMiniGameRequestTie(game));
|
game.broadcastToOwner(MaplePacketCreator.getMiniGameRequestTie(game));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (mode == Action.ANSWER_TIE.getCode()) {
|
} else if (mode == Action.ANSWER_TIE.getCode()) {
|
||||||
MapleMiniGame game = chr.getMiniGame();
|
MapleMiniGame game = chr.getMiniGame();
|
||||||
slea.readByte();
|
if (slea.readByte() != 0) {
|
||||||
if (game.getGameType().equals("omok")) {
|
game.minigameMatchDraw();
|
||||||
game.broadcast(MaplePacketCreator.getMiniGameTie(game));
|
} else {
|
||||||
|
game.denyTie(chr);
|
||||||
|
|
||||||
|
if (game.isOwner(chr)) {
|
||||||
|
game.broadcastToVisitor(MaplePacketCreator.getMiniGameDenyTie(game));
|
||||||
|
} else {
|
||||||
|
game.broadcastToOwner(MaplePacketCreator.getMiniGameDenyTie(game));
|
||||||
}
|
}
|
||||||
if (game.getGameType().equals("matchcard")) {
|
|
||||||
game.broadcast(MaplePacketCreator.getMatchCardTie(game));
|
|
||||||
}
|
}
|
||||||
} else if (mode == Action.SKIP.getCode()) {
|
} else if (mode == Action.SKIP.getCode()) {
|
||||||
MapleMiniGame game = chr.getMiniGame();
|
MapleMiniGame game = chr.getMiniGame();
|
||||||
@@ -391,7 +436,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
} else {
|
} else {
|
||||||
game.getOwner().getClient().announce(MaplePacketCreator.getMatchCardSelect(game, turn, slot, firstslot, turn));
|
game.getOwner().getClient().announce(MaplePacketCreator.getMatchCardSelect(game, turn, slot, firstslot, turn));
|
||||||
}
|
}
|
||||||
} else if ((game.getCardId(firstslot + 1)) == (game.getCardId(slot + 1))) {
|
} else if ((game.getCardId(firstslot)) == (game.getCardId(slot))) {
|
||||||
if (game.isOwner(chr)) {
|
if (game.isOwner(chr)) {
|
||||||
game.broadcast(MaplePacketCreator.getMatchCardSelect(game, turn, slot, firstslot, 2));
|
game.broadcast(MaplePacketCreator.getMatchCardSelect(game, turn, slot, firstslot, 2));
|
||||||
game.setOwnerPoints();
|
game.setOwnerPoints();
|
||||||
@@ -412,6 +457,13 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
Item item = chr.getInventory(ivType).getItem(slea.readShort());
|
Item item = chr.getInventory(ivType).getItem(slea.readShort());
|
||||||
short quantity = slea.readShort();
|
short quantity = slea.readShort();
|
||||||
byte targetSlot = slea.readByte();
|
byte targetSlot = slea.readByte();
|
||||||
|
|
||||||
|
if (item == null) {
|
||||||
|
c.announce(MaplePacketCreator.serverNotice(1, "Invalid item description."));
|
||||||
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (quantity < 1 || quantity > item.getQuantity()) {
|
if (quantity < 1 || quantity > item.getQuantity()) {
|
||||||
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough quantity of the item."));
|
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough quantity of the item."));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
@@ -448,7 +500,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
short bundles = slea.readShort();
|
short bundles = slea.readShort();
|
||||||
Item ivItem = chr.getInventory(ivType).getItem(slot);
|
Item ivItem = chr.getInventory(ivType).getItem(slot);
|
||||||
|
|
||||||
if (ivItem == null || ivItem.getFlag() == ItemConstants.UNTRADEABLE) {
|
if (ivItem == null || ivItem.isUntradeable()) {
|
||||||
c.announce(MaplePacketCreator.serverNotice(1, "Could not perform shop operation with that item."));
|
c.announce(MaplePacketCreator.serverNotice(1, "Could not perform shop operation with that item."));
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
return;
|
return;
|
||||||
@@ -632,6 +684,9 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
c.releaseClient();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isTradeOpen(MapleCharacter chr) {
|
private static boolean isTradeOpen(MapleCharacter chr) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
|
|||||||
@Override
|
@Override
|
||||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
MapleCharacter chr = c.getPlayer();
|
MapleCharacter chr = c.getPlayer();
|
||||||
chr.setPetLootCd(currentServerTime());
|
//chr.setPetLootCd(currentServerTime());
|
||||||
|
|
||||||
/*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8);
|
/*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8);
|
||||||
if(timeElapsed < 300) {
|
if(timeElapsed < 300) {
|
||||||
|
|||||||
@@ -273,20 +273,20 @@ public final class RingActionHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void giveMarriageRings(MapleCharacter player, MapleCharacter partner, int marriageRingId) {
|
public static void giveMarriageRings(MapleCharacter player, MapleCharacter partner, int marriageRingId) {
|
||||||
int ringid = MapleRing.createRing(marriageRingId, player, partner);
|
Pair<Integer, Integer> rings = MapleRing.createRing(marriageRingId, player, partner);
|
||||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||||
|
|
||||||
Item ringObj = ii.getEquipById(marriageRingId);
|
Item ringObj = ii.getEquipById(marriageRingId);
|
||||||
Equip ringEqp = (Equip) ringObj;
|
Equip ringEqp = (Equip) ringObj;
|
||||||
ringEqp.setRingId(ringid);
|
ringEqp.setRingId(rings.getLeft());
|
||||||
player.addMarriageRing(MapleRing.loadFromDb(ringid));
|
player.addMarriageRing(MapleRing.loadFromDb(rings.getLeft()));
|
||||||
MapleInventoryManipulator.addFromDrop(player.getClient(), ringEqp, false, -1);
|
MapleInventoryManipulator.addFromDrop(player.getClient(), ringEqp, false, -1);
|
||||||
player.broadcastMarriageMessage();
|
player.broadcastMarriageMessage();
|
||||||
|
|
||||||
ringObj = ii.getEquipById(marriageRingId);
|
ringObj = ii.getEquipById(marriageRingId);
|
||||||
ringEqp = (Equip) ringObj;
|
ringEqp = (Equip) ringObj;
|
||||||
ringEqp.setRingId(ringid + 1);
|
ringEqp.setRingId(rings.getRight());
|
||||||
partner.addMarriageRing(MapleRing.loadFromDb(ringid + 1));
|
partner.addMarriageRing(MapleRing.loadFromDb(rings.getRight()));
|
||||||
MapleInventoryManipulator.addFromDrop(partner.getClient(), ringEqp, false, -1);
|
MapleInventoryManipulator.addFromDrop(partner.getClient(), ringEqp, false, -1);
|
||||||
partner.broadcastMarriageMessage();
|
partner.broadcastMarriageMessage();
|
||||||
}
|
}
|
||||||
@@ -513,6 +513,6 @@ public final class RingActionHandler extends AbstractMaplePacketHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.getSession().write(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,10 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Acrylic (Terry Han)
|
* @author Terry Han (Acrylic)
|
||||||
*/
|
*/
|
||||||
public final class TouchingCashShopHandler extends AbstractMaplePacketHandler {
|
public final class TouchingCashShopHandler extends AbstractMaplePacketHandler {
|
||||||
|
@Override
|
||||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
|
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
|||||||
if (item == null) //hack
|
if (item == null) //hack
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
} else if (((item.getFlag() & ItemConstants.UNTRADEABLE) == ItemConstants.UNTRADEABLE) || (ii.isDropRestricted(item.getItemId()) && !MapleKarmaManipulator.hasKarmaFlag(item))) {
|
} else if (item.isUntradeable()) {
|
||||||
player.dropMessage(1, "You cannot trade this item.");
|
player.dropMessage(1, "You cannot trade this item.");
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
c.announce(MaplePacketCreator.enableActions());
|
||||||
return;
|
return;
|
||||||
@@ -299,7 +299,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
remove(c, itemId);
|
remove(c, itemId);
|
||||||
} else if (itemType == 508) { // graduation banner, thanks to tmskdl12
|
} else if (itemType == 508) { // graduation banner, thanks to tmskdl12. Also, thanks ratency for first pointing lack of Kite handling
|
||||||
MapleKite kite = new MapleKite(player, slea.readMapleAsciiString(), itemId);
|
MapleKite kite = new MapleKite(player, slea.readMapleAsciiString(), itemId);
|
||||||
|
|
||||||
if (!GameConstants.isFreeMarketRoom(player.getMapId())) {
|
if (!GameConstants.isFreeMarketRoom(player.getMapId())) {
|
||||||
@@ -517,7 +517,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
|||||||
|
|
||||||
Equip toScroll = (Equip) eitem;
|
Equip toScroll = (Equip) eitem;
|
||||||
if (toScroll.getUpgradeSlots() < 1) {
|
if (toScroll.getUpgradeSlots() < 1) {
|
||||||
c.getSession().write(MaplePacketCreator.getInventoryFull());
|
c.announce(MaplePacketCreator.getInventoryFull());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,10 +527,10 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
|||||||
player.toggleBlockCashShop();
|
player.toggleBlockCashShop();
|
||||||
|
|
||||||
final int curlevel = toScroll.getLevel();
|
final int curlevel = toScroll.getLevel();
|
||||||
c.getSession().write(MaplePacketCreator.sendVegaScroll(0x40));
|
c.announce(MaplePacketCreator.sendVegaScroll(0x40));
|
||||||
|
|
||||||
final Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, uitem.getItemId(), false, itemId, player.isGM());
|
final Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, uitem.getItemId(), false, itemId, player.isGM());
|
||||||
c.getSession().write(MaplePacketCreator.sendVegaScroll(scrolled.getLevel() > curlevel ? 0x41 : 0x43));
|
c.announce(MaplePacketCreator.sendVegaScroll(scrolled.getLevel() > curlevel ? 0x41 : 0x43));
|
||||||
//opcodes 0x42, 0x44: "this item cannot be used"; 0x39, 0x45: crashes
|
//opcodes 0x42, 0x44: "this item cannot be used"; 0x39, 0x45: crashes
|
||||||
|
|
||||||
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, uSlot, (short) 1, false);
|
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, uSlot, (short) 1, false);
|
||||||
@@ -555,7 +555,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
|||||||
player.equipChanged();
|
player.equipChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
client.getSession().write(MaplePacketCreator.enableActions());
|
client.announce(MaplePacketCreator.enableActions());
|
||||||
}
|
}
|
||||||
}, 1000 * 3);
|
}, 1000 * 3);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ package net.server.channel.handlers;
|
|||||||
import client.MapleClient;
|
import client.MapleClient;
|
||||||
import client.inventory.MapleInventoryType;
|
import client.inventory.MapleInventoryType;
|
||||||
import net.AbstractMaplePacketHandler;
|
import net.AbstractMaplePacketHandler;
|
||||||
import tools.MaplePacketCreator;
|
|
||||||
import tools.data.input.SeekableLittleEndianAccessor;
|
import tools.data.input.SeekableLittleEndianAccessor;
|
||||||
|
|
||||||
public final class UseChairHandler extends AbstractMaplePacketHandler {
|
public final class UseChairHandler extends AbstractMaplePacketHandler {
|
||||||
@@ -34,8 +33,7 @@ public final class UseChairHandler extends AbstractMaplePacketHandler {
|
|||||||
if (c.getPlayer().getInventory(MapleInventoryType.SETUP).findById(itemId) == null) {
|
if (c.getPlayer().getInventory(MapleInventoryType.SETUP).findById(itemId) == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c.getPlayer().setChair(itemId);
|
|
||||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showChair(c.getPlayer().getId(), itemId), false);
|
c.getPlayer().sitChair(itemId);
|
||||||
c.announce(MaplePacketCreator.enableActions());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import client.MapleClient;
|
|||||||
import client.MapleCharacter;
|
import client.MapleCharacter;
|
||||||
import client.MapleMount;
|
import client.MapleMount;
|
||||||
import client.inventory.Item;
|
import client.inventory.Item;
|
||||||
|
import client.inventory.MapleInventory;
|
||||||
import client.inventory.MapleInventoryType;
|
import client.inventory.MapleInventoryType;
|
||||||
import constants.ExpTable;
|
import constants.ExpTable;
|
||||||
import net.AbstractMaplePacketHandler;
|
import net.AbstractMaplePacketHandler;
|
||||||
@@ -45,10 +46,14 @@ public final class UseMountFoodHandler extends AbstractMaplePacketHandler {
|
|||||||
|
|
||||||
MapleCharacter chr = c.getPlayer();
|
MapleCharacter chr = c.getPlayer();
|
||||||
MapleMount mount = chr.getMount();
|
MapleMount mount = chr.getMount();
|
||||||
Item item = chr.getInventory(MapleInventoryType.USE).getItem(pos);
|
MapleInventory useInv = chr.getInventory(MapleInventoryType.USE);
|
||||||
if (item != null && item.getItemId() == itemid && mount != null) {
|
|
||||||
c.lockClient();
|
if (c.tryacquireClient()) {
|
||||||
try {
|
try {
|
||||||
|
useInv.lockInventory();
|
||||||
|
try {
|
||||||
|
Item item = useInv.getItem(pos);
|
||||||
|
if (item != null && item.getItemId() == itemid && mount != null) {
|
||||||
int curTiredness = mount.getTiredness();
|
int curTiredness = mount.getTiredness();
|
||||||
int healedTiredness = Math.min(curTiredness, 30);
|
int healedTiredness = Math.min(curTiredness, 30);
|
||||||
|
|
||||||
@@ -66,8 +71,12 @@ public final class UseMountFoodHandler extends AbstractMaplePacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, true, false);
|
MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, true, false);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.unlockClient();
|
useInv.unlockInventory();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
c.releaseClient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public final class WhisperHandler extends AbstractMaplePacketHandler {
|
|||||||
String recipient = slea.readMapleAsciiString();
|
String recipient = slea.readMapleAsciiString();
|
||||||
String text = slea.readMapleAsciiString();
|
String text = slea.readMapleAsciiString();
|
||||||
MapleCharacter player = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient);
|
MapleCharacter player = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient);
|
||||||
if(c.getPlayer().getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) {
|
if (c.getPlayer().getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (text.length() > Byte.MAX_VALUE && !player.isGM()) {
|
if (text.length() > Byte.MAX_VALUE && !player.isGM()) {
|
||||||
@@ -92,7 +92,7 @@ public final class WhisperHandler extends AbstractMaplePacketHandler {
|
|||||||
} else {
|
} else {
|
||||||
c.announce(MaplePacketCreator.getFindReply(victim.getName(), victim.getMap().getId(), 1));
|
c.announce(MaplePacketCreator.getFindReply(victim.getName(), victim.getMap().getId(), 1));
|
||||||
}
|
}
|
||||||
} else if (c.getPlayer().gmLevel() > 1) { // not found
|
} else if (c.getPlayer().isGM()) { // not found
|
||||||
try {
|
try {
|
||||||
Connection con = DatabaseConnection.getConnection();
|
Connection con = DatabaseConnection.getConnection();
|
||||||
PreparedStatement ps = con.prepareStatement("SELECT gm FROM characters WHERE name = ?");
|
PreparedStatement ps = con.prepareStatement("SELECT gm FROM characters WHERE name = ?");
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
|||||||
import client.MapleClient;
|
import client.MapleClient;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
public final class LoginPasswordHandler implements MaplePacketHandler {
|
public final class LoginPasswordHandler implements MaplePacketHandler {
|
||||||
|
|
||||||
@@ -45,6 +48,11 @@ public final class LoginPasswordHandler implements MaplePacketHandler {
|
|||||||
return !c.isLoggedIn();
|
return !c.isLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String hashpwSHA512(String pwd) throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||||
|
MessageDigest digester = MessageDigest.getInstance("SHA-512");
|
||||||
|
digester.update(pwd.getBytes("UTF-8"), 0, pwd.length());
|
||||||
|
return HexTool.toString(digester.digest()).replace(" ", "").toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||||
@@ -65,7 +73,7 @@ public final class LoginPasswordHandler implements MaplePacketHandler {
|
|||||||
con = DatabaseConnection.getConnection();
|
con = DatabaseConnection.getConnection();
|
||||||
ps = con.prepareStatement("INSERT INTO accounts (name, password, birthday, tempban) VALUES (?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS); //Jayd: Added birthday, tempban
|
ps = con.prepareStatement("INSERT INTO accounts (name, password, birthday, tempban) VALUES (?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS); //Jayd: Added birthday, tempban
|
||||||
ps.setString(1, login);
|
ps.setString(1, login);
|
||||||
ps.setString(2, BCrypt.hashpw(pwd, BCrypt.gensalt(12)));
|
ps.setString(2, ServerConstants.BCRYPT_MIGRATION ? BCrypt.hashpw(pwd, BCrypt.gensalt(12)) : hashpwSHA512(pwd));
|
||||||
ps.setString(3, "2018-06-20"); //Jayd's idea: was added to solve the MySQL 5.7 strict checking (birthday)
|
ps.setString(3, "2018-06-20"); //Jayd's idea: was added to solve the MySQL 5.7 strict checking (birthday)
|
||||||
ps.setString(4, "2018-06-20"); //Jayd's idea: was added to solve the MySQL 5.7 strict checking (tempban)
|
ps.setString(4, "2018-06-20"); //Jayd's idea: was added to solve the MySQL 5.7 strict checking (tempban)
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
@@ -74,7 +82,7 @@ public final class LoginPasswordHandler implements MaplePacketHandler {
|
|||||||
rs.next();
|
rs.next();
|
||||||
c.setAccID(rs.getInt(1));
|
c.setAccID(rs.getInt(1));
|
||||||
rs.close();
|
rs.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException | NoSuchAlgorithmException | UnsupportedEncodingException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
disposeSql(con, ps);
|
disposeSql(con, ps);
|
||||||
|
|||||||
@@ -695,7 +695,6 @@ public class AbstractPlayerInteraction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void removeHPQItems() {
|
public void removeHPQItems() {
|
||||||
int[] items = {4001095, 4001096, 4001097, 4001098, 4001099, 4001100, 4001101};
|
int[] items = {4001095, 4001096, 4001097, 4001098, 4001099, 4001100, 4001101};
|
||||||
for (int i = 0; i < items.length; i ++) {
|
for (int i = 0; i < items.length; i ++) {
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ public class EventInstanceManager {
|
|||||||
|
|
||||||
private void dismissEventTimer() {
|
private void dismissEventTimer() {
|
||||||
for(MapleCharacter chr: getPlayers()) {
|
for(MapleCharacter chr: getPlayers()) {
|
||||||
chr.getClient().getSession().write(MaplePacketCreator.removeClock());
|
chr.getClient().announce(MaplePacketCreator.removeClock());
|
||||||
}
|
}
|
||||||
|
|
||||||
event_schedule = null;
|
event_schedule = null;
|
||||||
|
|||||||
@@ -582,4 +582,9 @@ public class CashShop {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Item generateCouponItem(int itemId, short quantity) {
|
||||||
|
CashItem it = new CashItem(77777777, itemId, 7777, ItemConstants.isPet(itemId) ? 30 : 0, quantity, true);
|
||||||
|
return it.toItem();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -373,6 +373,7 @@ public class MapleItemInformationProvider {
|
|||||||
private static short getExtraSlotMaxFromPlayer(MapleClient c, int itemId) {
|
private static short getExtraSlotMaxFromPlayer(MapleClient c, int itemId) {
|
||||||
short ret = 0;
|
short ret = 0;
|
||||||
|
|
||||||
|
// thanks GMChuck for detecting player sensitive data being cached into getSlotMax
|
||||||
if (ItemConstants.isThrowingStar(itemId)) {
|
if (ItemConstants.isThrowingStar(itemId)) {
|
||||||
if(c.getPlayer().getJob().isA(MapleJob.NIGHTWALKER1)) {
|
if(c.getPlayer().getJob().isA(MapleJob.NIGHTWALKER1)) {
|
||||||
ret += c.getPlayer().getSkillLevel(SkillFactory.getSkill(NightWalker.CLAW_MASTERY)) * 10;
|
ret += c.getPlayer().getSkillLevel(SkillFactory.getSkill(NightWalker.CLAW_MASTERY)) * 10;
|
||||||
@@ -658,11 +659,11 @@ public class MapleItemInformationProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static short getMaximumShortMaxIfOverflow(int value1, int value2) {
|
private static short getMaximumShortMaxIfOverflow(int value1, int value2) {
|
||||||
return (short)Math.min(Short.MAX_VALUE, Math.max(value1, value2));
|
return (short) Math.min(Short.MAX_VALUE, Math.max(value1, value2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short getShortMaxIfOverflow(int value) {
|
private static short getShortMaxIfOverflow(int value) {
|
||||||
return (short)Math.min(Short.MAX_VALUE, value);
|
return (short) Math.min(Short.MAX_VALUE, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short chscrollRandomizedStat(int range) {
|
private static short chscrollRandomizedStat(int range) {
|
||||||
|
|||||||
@@ -94,12 +94,12 @@ public class MapleShop {
|
|||||||
if (c.getPlayer().getMeso() >= amount) {
|
if (c.getPlayer().getMeso() >= amount) {
|
||||||
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
||||||
if (!ItemConstants.isRechargeable(itemId)) { //Pets can't be bought from shops
|
if (!ItemConstants.isRechargeable(itemId)) { //Pets can't be bought from shops
|
||||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
MapleInventoryManipulator.addById(c, itemId, quantity, "", -1);
|
||||||
c.getPlayer().gainMeso(-amount, false);
|
c.getPlayer().gainMeso(-amount, false);
|
||||||
} else {
|
} else {
|
||||||
short slotMax = ii.getSlotMax(c, item.getItemId());
|
short slotMax = ii.getSlotMax(c, item.getItemId());
|
||||||
quantity = slotMax;
|
quantity = slotMax;
|
||||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
MapleInventoryManipulator.addById(c, itemId, quantity, "", -1);
|
||||||
c.getPlayer().gainMeso(-item.getPrice(), false);
|
c.getPlayer().gainMeso(-item.getPrice(), false);
|
||||||
}
|
}
|
||||||
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
|
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
|
||||||
@@ -115,12 +115,12 @@ public class MapleShop {
|
|||||||
if (c.getPlayer().getInventory(MapleInventoryType.ETC).countById(4310000) >= amount) {
|
if (c.getPlayer().getInventory(MapleInventoryType.ETC).countById(4310000) >= amount) {
|
||||||
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
||||||
if (!ItemConstants.isRechargeable(itemId)) {
|
if (!ItemConstants.isRechargeable(itemId)) {
|
||||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
MapleInventoryManipulator.addById(c, itemId, quantity, "", -1);
|
||||||
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, amount, false, false);
|
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, amount, false, false);
|
||||||
} else {
|
} else {
|
||||||
short slotMax = ii.getSlotMax(c, item.getItemId());
|
short slotMax = ii.getSlotMax(c, item.getItemId());
|
||||||
quantity = slotMax;
|
quantity = slotMax;
|
||||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
MapleInventoryManipulator.addById(c, itemId, quantity, "", -1);
|
||||||
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, amount, false, false);
|
MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, amount, false, false);
|
||||||
}
|
}
|
||||||
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
|
c.announce(MaplePacketCreator.shopTransaction((byte) 0));
|
||||||
@@ -138,9 +138,9 @@ public class MapleShop {
|
|||||||
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
||||||
if (ItemConstants.isPet(itemId)) {
|
if (ItemConstants.isPet(itemId)) {
|
||||||
int petid = MaplePet.createPet(itemId);
|
int petid = MaplePet.createPet(itemId);
|
||||||
MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1);
|
MapleInventoryManipulator.addById(c, itemId, quantity, "", petid, -1);
|
||||||
} else {
|
} else {
|
||||||
MapleInventoryManipulator.addById(c, itemId, quantity);
|
MapleInventoryManipulator.addById(c, itemId, quantity, "", -1, -1);
|
||||||
}
|
}
|
||||||
c.getPlayer().gainMeso(diff, false);
|
c.getPlayer().gainMeso(diff, false);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
|
|||||||
if (mpsi.getItem().getInventoryType().equals(MapleInventoryType.EQUIP)) {
|
if (mpsi.getItem().getInventoryType().equals(MapleInventoryType.EQUIP)) {
|
||||||
MapleInventoryManipulator.addFromDrop(c, mpsi.getItem(), false);
|
MapleInventoryManipulator.addFromDrop(c, mpsi.getItem(), false);
|
||||||
} else {
|
} else {
|
||||||
MapleInventoryManipulator.addById(c, mpsi.getItem().getItemId(), (short) (mpsi.getBundles() * mpsi.getItem().getQuantity()), null, -1, mpsi.getItem().getFlag(), mpsi.getItem().getExpiration());
|
MapleInventoryManipulator.addById(c, mpsi.getItem().getItemId(), (short) (mpsi.getBundles() * mpsi.getItem().getQuantity()), mpsi.getItem().getOwner(), -1, mpsi.getItem().getFlag(), mpsi.getItem().getExpiration());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,12 +43,12 @@ public class MapleKite extends AbstractMapleMapObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendDestroyData(MapleClient client) {
|
public void sendDestroyData(MapleClient client) {
|
||||||
client.getSession().write(makeDestroyData());
|
client.announce(makeDestroyData());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendSpawnData(MapleClient client) {
|
public void sendSpawnData(MapleClient client) {
|
||||||
client.getSession().write(makeSpawnData());
|
client.announce(makeSpawnData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public final byte[] makeSpawnData() {
|
public final byte[] makeSpawnData() {
|
||||||
|
|||||||
@@ -3882,7 +3882,7 @@ public class MapleMap {
|
|||||||
|
|
||||||
public void spawnHorntailOnGroundBelow(final Point targetPoint) { // ayy lmao
|
public void spawnHorntailOnGroundBelow(final Point targetPoint) { // ayy lmao
|
||||||
MapleMonster htIntro = MapleLifeFactory.getMonster(8810026);
|
MapleMonster htIntro = MapleLifeFactory.getMonster(8810026);
|
||||||
spawnMonsterOnGroundBelow(htIntro, targetPoint);
|
spawnMonsterOnGroundBelow(htIntro, targetPoint); // htintro spawn animation converting into horntail detected thanks to Arnah
|
||||||
|
|
||||||
final MapleMonster ht = MapleLifeFactory.getMonster(8810018);
|
final MapleMonster ht = MapleLifeFactory.getMonster(8810018);
|
||||||
ht.setParentMobOid(htIntro.getObjectId());
|
ht.setParentMobOid(htIntro.getObjectId());
|
||||||
|
|||||||
@@ -427,21 +427,14 @@ public class MapleMapFactory {
|
|||||||
public Map<Integer, MapleMap> getMaps() {
|
public Map<Integer, MapleMap> getMaps() {
|
||||||
mapsRLock.lock();
|
mapsRLock.lock();
|
||||||
try {
|
try {
|
||||||
return Collections.unmodifiableMap(maps);
|
return new HashMap<>(maps);
|
||||||
} finally {
|
} finally {
|
||||||
mapsRLock.unlock();
|
mapsRLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
Collection<MapleMap> mapValues;
|
Collection<MapleMap> mapValues = getMaps().values();
|
||||||
|
|
||||||
mapsRLock.lock();
|
|
||||||
try {
|
|
||||||
mapValues = maps.values();
|
|
||||||
} finally {
|
|
||||||
mapsRLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(MapleMap map: mapValues) {
|
for(MapleMap map: mapValues) {
|
||||||
map.dispose();
|
map.dispose();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user