Party Search + Conditional Buffs
Revised skillbook drops. New drop chances are related to the holder's level and boss flag. Adjusted party bonus EXP gains. The level difference calculation now only takes into account party members that participated in the action. Implemented Party Search in the source. Refactored command classes initialization to take place when booting up the server. Implemented support for conditional buffs (e.g. card buffs that takes place only in certain areas). Implemented topological sorting when updating buffs to the player, this allows a better vision of buff streaks to the player (buff-applying the original way assumes stat override client-side, to circumvent that this algorithm makes up for the best-fit scenario). Fixed Arans not taking Dojo's attack speed buff properly. Fixed pets being improperly removed from the DB after performing certain inventory actions.
This commit is contained in:
@@ -103,6 +103,10 @@
|
||||
/tools/MapleReactorDropFetcher/dist/
|
||||
/tools/MapleReactorDropFetcher/nbproject/
|
||||
|
||||
/tools/MapleSkillbookChanceFetcher/build/
|
||||
/tools/MapleSkillbookChanceFetcher/dist/
|
||||
/tools/MapleSkillbookChanceFetcher/nbproject/
|
||||
|
||||
/tools/MapleSkillbookStackUpdate/build/
|
||||
/tools/MapleSkillbookStackUpdate/dist/
|
||||
/tools/MapleSkillbookStackUpdate/nbproject/
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# Docker support, thanks to xinyifly
|
||||
|
||||
FROM openjdk:7-alpine
|
||||
RUN apk -U add tini
|
||||
WORKDIR /mnt
|
||||
COPY ./ ./
|
||||
RUN sh ./posix-compile.sh
|
||||
EXPOSE 8484 7575 7576 7577
|
||||
CMD exec tini -- sh ./docker-launch.sh
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
sed -i "s/HOST=.*/HOST=${HOST}/" configuration.ini
|
||||
sed -i "s|URL=.*|URL=${URL}|" configuration.ini
|
||||
sed -i "s/DB_USER=.*/DB_USER=${DB_USER}/" configuration.ini
|
||||
sed -i "s/DB_PASS=.*/DB_PASS=${DB_PASS}/" configuration.ini
|
||||
|
||||
exec sh ./posix-launch.sh
|
||||
@@ -1840,6 +1840,7 @@ Revisado refatoração recente em acesso a valores de stats de jogadores levando
|
||||
24 - 26 Abril 2019,
|
||||
Ajustado levemente taxa de respawn de mobs quando não se está usando a flag de respawn completo.
|
||||
Ajustado ganhos de stats de ataque ao passar de nível weapons, ganha-se menos do stat que não é a afinidade (watk/matk).
|
||||
Implementado sistema de Party Search no fonte. Líderes de party são servidos em FIFO, buscando melhores jogadores na faixa escolhida sempre que possível. Thread separada lida com organização e convites automatizados para jogadores.
|
||||
Corrigido drops de mesos sendo bloqueados para drops rápidos de mesos, indevidamente dificultando jogabilidade para certas classes.
|
||||
Corrigido caso de XML parser em MapleSkillBookInformationParser não lidando com terminadores "/>" corretamente.
|
||||
|
||||
@@ -1851,5 +1852,23 @@ Adicionado server flag para checagem de IP's ao logar jogadores.
|
||||
Corrigido mobskills não sendo devidamente aplicados devido a um deslize anterior que tentaria aplicar indevidamente 2x "uso de skill" (uma das vezes deveria ser somente checagem de rotina).
|
||||
Corrigido puppets de arqueiros interrompendo mob statuses para o dono ao serem lançados em campo.
|
||||
|
||||
03 Maio 2019,
|
||||
Revisado chance de drops de skillbooks. Chance de drops agora está relacionado ao nível do mob em conjunto com disponibilidade do mesmo (em bosses chances são melhores de sair o item).
|
||||
Ajustado ganhos de party bonus EXP. Penalidade por diferença de nível agora somente leva em conta membros de equipe que efetivamente participaram da ação.
|
||||
Ajustado as mecânicas da Party Search recentemente implementadas, de forma que se comporte bem em jogo.
|
||||
Ajustado inicialização do sistema de comandos, agora atuando na inicialização do server, evitando bottleneck de primeira instanciação.
|
||||
|
||||
04 Maio 2019,
|
||||
Corrigido visão de mob statuses sendo interrompido para o novo controlador ao realizar troca de controladores.
|
||||
|
||||
07 - 08 Maio 2019,
|
||||
Adicionado ao sistema de buffs suporte para condicionais de atuação (e.g. buff tendo efeito ativo dependendo do mapa de onde o jogador se encontra).
|
||||
Implementado ordenação topológica na atualização de buffs. Sistema aponta um "melhor caminho" na atualização dos buffs, desta forma mostrando visualmente ao jogador certas combinações de buffs aplicados que anteriormente falhava em mostrar (e.g. Congrats from GM & Chocolate Wafer).
|
||||
Corrigido Arans não recebendo corretamente buff de velocidade de ataque do Dojo.
|
||||
Implementado convite de Party Search sensível ao mapa onde os jogadores líder e convidado se encontram. O sistema somente detecta para convites jogadores em mapas "próximos".
|
||||
|
||||
12 Maio 2019,
|
||||
Corrigido pets sendo indevidamente removido da DB ao realizar operações de retirada do inventário.
|
||||
|
||||
15 Maio 2019,
|
||||
Revisado, via testes unitários, robustez dos registros/buscas de jogadores e fluidez do sistema de Party Search.
|
||||
@@ -58,7 +58,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Primrose Hill>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nI'm Tory. Inside here is a beautiful hill where the primrose blooms. There's a tiger that lives in the hill, Growlie, and he seems to be looking for something to eat. Would you like to head over to the hill of primrose and join forces with your party members to help Growlie out?#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to redeem an instance hat.");
|
||||
cm.sendSimple("#e#b<Party Quest: Primrose Hill>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nI'm Tory. Inside here is a beautiful hill where the primrose blooms. There's a tiger that lives in the hill, Growlie, and he seems to be looking for something to eat. Would you like to head over to the hill of primrose and join forces with your party members to help Growlie out?#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to redeem an instance hat.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -81,7 +81,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else if (selection == 2) {
|
||||
cm.sendOk("#e#b<Party Quest: Primrose Hill>#k#n\r\nCollect primrose seeds from the flowers at the bottom part of the map and drop them by the platforms above the stage. Primrose seed color must match to grow the seeds, so test until you find the correct combination. When all the seeds have been planted, that is, starting second part of the mission, scout the Moon Bunny while it prepares Rice Cakes for the hungry Growlie. Once Growlie becomes satisfied, your mission is complete.");
|
||||
|
||||
@@ -102,7 +102,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Premium Road - " + levels[selection] + ">\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThe #p1052014# operates differently than the common ones. They do not use mesos or gachapon tickets, rather #rERASERS#k, that can be obtained by completing the missions held on the Premium Road. To go there, you must find partners and attend to a Party Quest. When teamed up and ready, have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Premium Road - " + levels[selection] + ">\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThe #p1052014# operates differently than the common ones. They do not use mesos or gachapon tickets, rather #rERASERS#k, that can be obtained by completing the missions held on the Premium Road. To go there, you must find partners and attend to a Party Quest. When teamed up and ready, have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 2) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -125,7 +125,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Premium Road>#k#n\r\nOn the maps ahead, you will face many common-leveled mobs to face on. Grind all the required coupons from them and give it to me. All members will then receive a eraser, corresponding with the level faced. Insert on the machine #bmany of the same eraser or multiple different ones#k to have a better chance on greater prizes.");
|
||||
|
||||
@@ -58,7 +58,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Tower of Goddess>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nWould you like to assemble or join a team to solve the puzzles of the #bTower of Goddess#k? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to reclaim a prize.");
|
||||
cm.sendSimple("#e#b<Party Quest: Tower of Goddess>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nWould you like to assemble or join a team to solve the puzzles of the #bTower of Goddess#k? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to reclaim a prize.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -81,7 +81,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else if (selection == 2) {
|
||||
cm.sendOk("#e#b<Party Quest: Tower of Goddess>#k#n\r\nOur goddess has been missing since some time ago, rumor has it She has been seen last time inside the Tower of Goddess. Furthermore, our sanctuary has been seized by the overwhelming forces of the pixies, those beings that are recently wandering at the outskirts of Orbis. Their leader, Papa Pixie, currently holds the throne and may know Her whereabouts, so we urge to find a composition of brave heroes to charge into and claim back our sanctuary and rescue Her. If your team is able to be a composite of every job niche available (Warrior, Magician, Bowman, Thief and Pirate), you guys will receive my blessings to aid you in battle. Will you aid us?\r\n");
|
||||
|
||||
@@ -38,7 +38,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Dimensional Schism>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nYou can't go any higher because of the extremely dangerous creatures above. Would you like to collaborate with party members to complete the quest? If so, please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Dimensional Schism>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nYou can't go any higher because of the extremely dangerous creatures above. Would you like to collaborate with party members to complete the quest? If so, please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -61,7 +61,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Dimensional Schism>#k#n\r\nA Dimensional Schism has appeared in #b#m220000000#!#k We desperately need brave adventurers who can defeat the intruding monsters. Please, party with some dependable allies to save #m220000000#! You must pass through various stages by defeating monsters and solving quizzes, and ultimately defeat #r#o9300012##k.");
|
||||
|
||||
@@ -66,7 +66,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Elemental Thanatos>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nYou are looking for Elemental Thanatos, right? If you team up with another mage, with the opposite elemental affinity as yours, you guys will be able to overcome them. As a leader, talk to me when you feel ready to go.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Elemental Thanatos>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nYou are looking for Elemental Thanatos, right? If you team up with another mage, with the opposite elemental affinity as yours, you guys will be able to overcome them. As a leader, talk to me when you feel ready to go.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -89,7 +89,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Elemental Thanatos>#k#n\r\n Team up with another mage with #rdifferent elemental affinity#k before entering the stage. This team aspect is crucial to overcome the elementals inside.");
|
||||
|
||||
@@ -64,7 +64,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Horntail Trial Grounds>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThis is the path to Horntail's lair. If you want to face him, you and your team shall be tested on the trial grounds ahead.#b\r\n#L0#Let us pass to the trial grounds.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Horntail Trial Grounds>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThis is the path to Horntail's lair. If you want to face him, you and your team shall be tested on the trial grounds ahead.#b\r\n#L0#Let us pass to the trial grounds.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -87,7 +87,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if(selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Horntail Trial Grounds>#k#n\r\nAs the gatekeeper of Horntail's lair, I will grant access #bjust to those worthy#k of his presence. Even for those people, the path inside is that of a maze, full of branches and trials. However, those #radept at fighting squad bosses#k have a better chance to stand to our leader, although those #rof our kind#k have a shabby chance as well.");
|
||||
|
||||
@@ -57,7 +57,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Pirate Ship>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nHelp! My son has been kidnapped and is bound on the hands of the fearful #rLord Pirate#k. I need your help... Would you please assemble or join a team to save him? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Pirate Ship>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nHelp! My son has been kidnapped and is bound on the hands of the fearful #rLord Pirate#k. I need your help... Would you please assemble or join a team to save him? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -80,7 +80,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Pirate Ship>#k#n\r\nIn this PQ, your mission is to progressively make your way through the ship, taking on all pirates and baddies in your path. Reaching the #rLord Pirate#k, depending on how many great chests you opened on the stages before, the boss will reveal himself even more powerful, so stay alert. Said chests, if opened, gives many extra rewards to your crew, it's worth a shot! Good luck.");
|
||||
|
||||
@@ -54,7 +54,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Save Delli>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nAh, #r#p1095000##k sent you here? Is she worried about me? ... I'm terribly sorry to hear that, but I can't really go back just yet, some monsters are under the Black Mage's influence, and it's up to me to liberate them! ... It seems you're not going to accept that either, huh? Would you like to collaborate with party members to help me? If so, please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Save Delli>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nAh, #r#p1095000##k sent you here? Is she worried about me? ... I'm terribly sorry to hear that, but I can't really go back just yet, some monsters are under the Black Mage's influence, and it's up to me to liberate them! ... It seems you're not going to accept that either, huh? Would you like to collaborate with party members to help me? If so, please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else {
|
||||
cm.sendYesNo("The mission succeeded, thanks for escorting me! I can lead you to #b#m120000104##k, are you ready?");
|
||||
}
|
||||
@@ -81,7 +81,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Save Delli>#k#n\r\n A ambush is under way! I must stand on the field for around 6 minutes to complete the liberation, please protect me during that time so that my mission is completed.");
|
||||
|
||||
@@ -65,7 +65,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Romeo and Juliet>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nMy beloved Romeo has been kidnapped! Although he is Zenumist's, I can't stand by and just see him suffer just because of this foolish clash. I need you and your colleagues help to save him! Please, help us!! Please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Romeo and Juliet>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nMy beloved Romeo has been kidnapped! Although he is Zenumist's, I can't stand by and just see him suffer just because of this foolish clash. I need you and your colleagues help to save him! Please, help us!! Please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -88,7 +88,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Romeo and Juliet>#k#n\r\nNot long ago, a scientist named Yulete has been banished from this town because of his researches of combined alchemies of Alcadno's and Zenumist's. Because of the immensurable amount of power coming from this combination, it is forbidden by law to study both. Yet, he ignored this law and got hands in both researches. As a result, he has been exiled.\r\nHe is now retaliating, already took my beloved one and his next target is me, as we are big pictures of Magatia, successors of both societies. But I'm not afraid. We must recover him at all costs!\r\n");
|
||||
|
||||
@@ -65,7 +65,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Romeo and Juliet>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nMy beloved Juliet has been kidnapped! Although she is Alcadno's, I can't stand by and just see her suffer just because of this foolish clash. I need you and your colleagues help to save her! Please, help us!! Please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Romeo and Juliet>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nMy beloved Juliet has been kidnapped! Although she is Alcadno's, I can't stand by and just see her suffer just because of this foolish clash. I need you and your colleagues help to save her! Please, help us!! Please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -88,7 +88,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Romeo and Juliet>#k#n\r\nNot long ago, a scientist named Yulete has been banished from this town because of his researches of combined alchemies of Alcadno's and Zenumist's. Because of the immensurable amount of power coming from this combination, it is forbidden by law to study both. Yet, he ignored this law and got hands in both researches. As a result, he has been exiled.\r\nHe is now retaliating, already took my beloved one and his next target is me, as we are big pictures of Magatia, successors of both societies. But I'm not afraid. We must recover her at all costs!\r\n");
|
||||
|
||||
@@ -57,7 +57,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Forest of Poison Haze>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nWould you like to assemble or join a team to solve the puzzles of the #bForest of Poison Haze#k? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to reclaim a prize.");
|
||||
cm.sendSimple("#e#b<Party Quest: Forest of Poison Haze>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nWould you like to assemble or join a team to solve the puzzles of the #bForest of Poison Haze#k? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.\r\n#L3#I would like to reclaim a prize.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -80,7 +80,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else if (selection == 2) {
|
||||
cm.sendOk("#e#b<Party Quest: Forest of Poison Haze>#k#n\r\nIn this PQ, your mission is to progressively make your way through the woods, taking on all baddies in your path, solving many puzzles you encounter and rallying yourselves to take the best of teamwork to overcome time limits and powerful creatures. Clearing the final boss, your team have a chance to obtain a marble that, #bwhen dropped by the fountain at the exit map#k, will guarantee the team extra prizes. Good luck.");
|
||||
|
||||
@@ -122,7 +122,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Boss Rush>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nWould you like to collaborate with party members to complete the expedition, or are you brave enough to take it on all by yourself? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Boss Rush>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nWould you like to collaborate with party members to complete the expedition, or are you brave enough to take it on all by yourself? Have your #bparty leader#k talk to me or make yourself a party.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
}
|
||||
} else if (status == 1) {
|
||||
if(state == 3) {
|
||||
@@ -171,7 +171,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Boss Rush>#k#n\r\nBrave adventurers from all over the places travels here to test their skills and abilities in combat, as they face even more powerful bosses from MapleStory. Join forces with fellow adventurers or face all the burden by yourself and receive all the glory, it is up to you. REWARDS are given accordingly to how far the adventurers reach and extra prizes may are given to a random member of the party, all attributed at the end of an expedition.\r\n\r\nThis instance also supports #bmultiple lobbies for matchmaking several ranges of team levels#k at once: team up with players with lower level if you want better chances to swiftly set up a boss rush for your team.");
|
||||
|
||||
@@ -62,7 +62,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: 1st Accompaniment>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nHow about you and your party members collectively beating a quest? Here you'll find obstacles and problems where you won't be able to beat it without great teamwork. If you want to try it, please tell the #bleader of your party#k to talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: 1st Accompaniment>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nHow about you and your party members collectively beating a quest? Here you'll find obstacles and problems where you won't be able to beat it without great teamwork. If you want to try it, please tell the #bleader of your party#k to talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
}
|
||||
} else if (status == 1) {
|
||||
if(state == 1) {
|
||||
@@ -91,7 +91,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: 1st Accompaniment>#k#n\r\nYour party must pass through many obstacles and puzzles while traversing the sub-objectives of this Party Quest. Coordinate with your team in order to further advance and defeat the final boss and collect the dropped item in order to access the rewards and bonus stage.");
|
||||
|
||||
@@ -61,7 +61,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Ludibrium Maze>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThis is the entrance to the Ludibrium Maze. Enjoy!\r\n#b#L0#Enter the Lubidrium Maze#l\r\n#L1#I want to find party members.\r\n#L2#What is the Ludibrium Maze?");
|
||||
cm.sendSimple("#e#b<Party Quest: Ludibrium Maze>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nThis is the entrance to the Ludibrium Maze. Enjoy!\r\n#b#L0#Enter the Lubidrium Maze#l\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#What is the Ludibrium Maze?");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -84,7 +84,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Ludibrium Maze>#k#n\r\nThis maze is available to all parties of 3 or more members, and all participants must be between Level 51~70. You will be given 15 minutes to escape the maze. At the center of the room, there will be a Warp Portal set up to transport you to a different room. These portals will transport you to other rooms where you'll (hopefully) find the exit. Pietri will be waiting at the exit, so all you need to do is talk to him, and he'll let you out. Break all the boxes located in the room, and a monster inside the box will drop a coupon. After escaping the maze, you will be awarded with EXP based on the coupons collected. Additionally, if the leader possesses at least 30 coupons, then a special gift will be presented to the party. If you cannot escape the maze within the allotted 15 minutes, you will receive 0 EXP for your time in the maze. If you decide to log off while you're in the maze, you will be automatically kicked out of the maze. Even if the members of the party leave in the middle of the quest, the remaining members will be able to continue on with the quest, except if they run out of the minimum amount of party members in the maze. If you are in critical condition and unable to hunt down the monsters, you may avoid them to save yourself. Your fighting spirit and wits will be tested! Good luck!");
|
||||
|
||||
@@ -72,7 +72,7 @@ function recruitPqAction(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Holiday>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nHow about you and your party members collectively beating a quest? Here you'll find obstacles and problems where you won't be able to beat it without great teamwork. If you want to try it, please tell the #bleader of your party#k to talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Holiday>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nHow about you and your party members collectively beating a quest? Here you'll find obstacles and problems where you won't be able to beat it without great teamwork. If you want to try it, please tell the #bleader of your party#k to talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -95,7 +95,8 @@ function recruitPqAction(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Holiday>#k#n\r\n\r\nJoin in with your team to build up the Snowman that will protect Happyville from the misdoings of Scrooge. While inside, work out with your team to protect it at any means necessary while collecting Snow Vigor that will help on the build up of the Snowman.");
|
||||
|
||||
@@ -57,7 +57,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: Amorian Challenge>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nIf you're brave enough to attempt the Amorian Challenge, join with others like you and let your #bparty leader#k talk to me. If a party filled with whole married couples register to the challenge, better prizes awaits there.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: Amorian Challenge>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nIf you're brave enough to attempt the Amorian Challenge, join with others like you and let your #bparty leader#k talk to me. If a party filled with whole married couples register to the challenge, better prizes awaits there.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -80,7 +80,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: Amorian Challenge>#k#n\r\nI am Amos, hoster of the well-round famed Amorian Challenge. The instance consist of many team puzzles, where cooperation is the fundamental key for progress. Team up with other players to attempt for the bonus stage, where many goodies can be obtained at the end of the instance. If an all-couple party is formed, they can get even better prizes on the extra bonus stage.");
|
||||
|
||||
@@ -56,7 +56,7 @@ function action(mode, type, selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
cm.sendSimple("#e#b<Party Quest: MV's Lair>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nYou can't go any further because of the extremely dangerous creatures lying ahead. Would you like to collaborate with party members to complete the quest? If so, please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I want to find party members.\r\n#L2#I would like to hear more details.");
|
||||
cm.sendSimple("#e#b<Party Quest: MV's Lair>\r\n#k#n" + em.getProperty("party") + "\r\n\r\nYou can't go any further because of the extremely dangerous creatures lying ahead. Would you like to collaborate with party members to complete the quest? If so, please have your #bparty leader#k talk to me.#b\r\n#L0#I want to participate in the party quest.\r\n#L1#I would like to " + (cm.getPlayer().isRecvPartySearchInviteEnabled() ? "disable" : "enable") + " Party Search.\r\n#L2#I would like to hear more details.");
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
if (cm.getParty() == null) {
|
||||
@@ -79,7 +79,8 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (selection == 1) {
|
||||
cm.sendOk("Try using a Super Megaphone or asking your buddies or guild to join!");
|
||||
var psState = cm.getPlayer().toggleRecvPartySearchInvite();
|
||||
cm.sendOk("Your Party Search status is now: #b" + (psState ? "enabled" : "disabled") + "#k. Talk to me whenever you want to change it back.");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("#e#b<Party Quest: MV's Lair>#k#n\r\nMV appeared once more, disrupting the welfare of the people of New Leaf City. Join forces with other maplers to fend off this sudden attack. After defeating MV and his minions, fetch your prizes at MV's treasure room.");
|
||||
|
||||
@@ -75,6 +75,7 @@ function writeFeatureTab_Quests() {
|
||||
}
|
||||
|
||||
function writeFeatureTab_PlayerSocialNetwork() {
|
||||
addFeature("Party Search fully functional.");
|
||||
addFeature("Guild and Alliance system fully functional.");
|
||||
addFeature("Guild contract system held in Guild Headquarters.");
|
||||
addFeature("Party for novices-only.");
|
||||
@@ -180,6 +181,7 @@ function writeFeatureTab_Playerpotentials() {
|
||||
addFeature("Character slots per world/server-wide.");
|
||||
addFeature("Optional cash shop inventory separated by classes.");
|
||||
addFeature("Players manage 'same-typed' invites exclusively.");
|
||||
addFeature("Player buffs with conditional active effects.");
|
||||
}
|
||||
|
||||
function writeFeatureTab_Serverpotentials() {
|
||||
|
||||
+2
-2
@@ -184,7 +184,7 @@ CREATE TABLE IF NOT EXISTS `characters` (
|
||||
`dataString` varchar(64) NOT NULL DEFAULT '',
|
||||
`lastLogoutTime` timestamp NOT NULL DEFAULT '2015-01-01 05:00:00',
|
||||
`lastExpGainTime` timestamp NOT NULL DEFAULT '2015-01-01 05:00:00',
|
||||
`pendantExp` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`partySearch` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`jailexpire` bigint(20) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `accountid` (`accountid`),
|
||||
@@ -12750,7 +12750,7 @@ INSERT IGNORE INTO `temp_data` (`dropperid`, `itemid`, `minimum_quantity`, `maxi
|
||||
(8150200, 2290135, 1, 1, 0, 1500),
|
||||
(8800002, 2280013, 1, 1, 0, 45000),
|
||||
(8140600, 2290132, 1, 1, 0, 1500),
|
||||
(851000, 2290132, 1, 1, 0, 15000),
|
||||
(8510000, 2290132, 1, 1, 0, 15000),
|
||||
(8520000, 2290132, 1, 1, 0, 15000),
|
||||
(8810018, 2290133, 1, 1, 0, 45000),
|
||||
(8200008, 2290133, 1, 1, 0, 1500),
|
||||
|
||||
+619
-1
@@ -17212,7 +17212,7 @@ USE `heavenms`;
|
||||
(9400014, 2040719, 1, 4, 0, 10000),
|
||||
(9400014, 1102030, 1, 1, 0, 40000),
|
||||
(9400014, 1032027, 1, 1, 0, 40000),
|
||||
(9400014, 1402037, 1, 1, 0, 40000),
|
||||
(9400014, 1402037, 1, 1, 0, 40000), # thanks Feras & Kitty for noticing issues with Stonetooth Sword layout
|
||||
(9400014, 1372011, 1, 1, 0, 40000),
|
||||
(8200008, 4000453, 1, 1, 0, 200000),
|
||||
(8200008, 4000459, 1, 1, 0, 200000),
|
||||
@@ -23924,3 +23924,621 @@ SET minimum_quantity = CASE
|
||||
;
|
||||
|
||||
UPDATE drop_data SET `chance`=1287 WHERE `chance`=1500;
|
||||
|
||||
# MapleSkillbookChanceFetcher! Tuning up some skillbook drop chances in order to fit their dropper's availability (whether's a boss or not) and level.
|
||||
REPLACE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) VALUES
|
||||
(851000, 2290132, 1, 1, 0, 3861),
|
||||
(7090000, 2290087, 1, 1, 0, 40000),
|
||||
(8090000, 2290045, 1, 1, 0, 40000),
|
||||
(8140103, 2290044, 1, 1, 0, 2000),
|
||||
(8140511, 2290009, 1, 1, 0, 2000),
|
||||
(8140511, 2290050, 1, 1, 0, 2000),
|
||||
(8140511, 2290083, 1, 1, 0, 2000),
|
||||
(8140511, 2290134, 1, 1, 0, 6000),
|
||||
(8140512, 2290013, 1, 1, 0, 2000),
|
||||
(8140512, 2290067, 1, 1, 0, 2000),
|
||||
(8140512, 2290082, 1, 1, 0, 2000),
|
||||
(8140512, 2290097, 1, 1, 0, 2000),
|
||||
(8140512, 2290116, 1, 1, 0, 2000),
|
||||
(8140512, 2290131, 1, 1, 0, 6000),
|
||||
(8140600, 2290132, 1, 1, 0, 6000),
|
||||
(8140700, 2290106, 1, 1, 0, 2000),
|
||||
(8140700, 2290126, 1, 1, 0, 6000),
|
||||
(8140701, 2290122, 1, 1, 0, 2000),
|
||||
(8140702, 2290112, 1, 1, 0, 2000),
|
||||
(8140703, 2290088, 1, 1, 0, 2000),
|
||||
(8140703, 2290099, 1, 1, 0, 2000),
|
||||
(8141000, 2290082, 1, 1, 0, 2000),
|
||||
(8141000, 2290097, 1, 1, 0, 2000),
|
||||
(8141100, 2280005, 1, 1, 0, 2000),
|
||||
(8141300, 2290098, 1, 1, 0, 2000),
|
||||
(8142100, 2290032, 1, 1, 0, 2000),
|
||||
(8142100, 2290082, 1, 1, 0, 2000),
|
||||
(8142100, 2290114, 1, 1, 0, 2000),
|
||||
(8143000, 2280004, 1, 1, 0, 2000),
|
||||
(8150000, 2280013, 1, 1, 0, 120000),
|
||||
(8150000, 2290070, 1, 1, 0, 40000),
|
||||
(8150000, 2290091, 1, 1, 0, 40000),
|
||||
(8150100, 2290042, 1, 1, 0, 2000),
|
||||
(8150100, 2290053, 1, 1, 0, 2000),
|
||||
(8150100, 2290073, 1, 1, 0, 2000),
|
||||
(8150100, 2290102, 1, 1, 0, 2000),
|
||||
(8150100, 2290118, 1, 1, 0, 2000),
|
||||
(8150101, 2290017, 1, 1, 0, 2000),
|
||||
(8150101, 2290021, 1, 1, 0, 2000),
|
||||
(8150101, 2290035, 1, 1, 0, 2000),
|
||||
(8150101, 2290042, 1, 1, 0, 2000),
|
||||
(8150101, 2290052, 1, 1, 0, 2000),
|
||||
(8150101, 2290102, 1, 1, 0, 2000),
|
||||
(8150200, 2290024, 1, 1, 0, 2000),
|
||||
(8150200, 2290100, 1, 1, 0, 2000),
|
||||
(8150200, 2290135, 1, 1, 0, 6000),
|
||||
(8150201, 2290004, 1, 1, 0, 2000),
|
||||
(8150201, 2290006, 1, 1, 0, 2000),
|
||||
(8150201, 2290024, 1, 1, 0, 2000),
|
||||
(8150201, 2290036, 1, 1, 0, 2000),
|
||||
(8150201, 2290056, 1, 1, 0, 2000),
|
||||
(8150201, 2290072, 1, 1, 0, 2000),
|
||||
(8150201, 2290078, 1, 1, 0, 2000),
|
||||
(8150201, 2290117, 1, 1, 0, 2000),
|
||||
(8150300, 2290003, 1, 1, 0, 2000),
|
||||
(8150300, 2290033, 1, 1, 0, 2000),
|
||||
(8150300, 2290111, 1, 1, 0, 2000),
|
||||
(8150300, 2290120, 1, 1, 0, 2000),
|
||||
(8150300, 2290127, 1, 1, 0, 6000),
|
||||
(8150301, 2290023, 1, 1, 0, 2000),
|
||||
(8150301, 2290029, 1, 1, 0, 2000),
|
||||
(8150301, 2290101, 1, 1, 0, 2000),
|
||||
(8150301, 2290107, 1, 1, 0, 2000),
|
||||
(8150302, 2290010, 1, 1, 0, 2000),
|
||||
(8150302, 2290019, 1, 1, 0, 2000),
|
||||
(8150302, 2290026, 1, 1, 0, 2000),
|
||||
(8150302, 2290076, 1, 1, 0, 2000),
|
||||
(8150302, 2290085, 1, 1, 0, 2000),
|
||||
(8150302, 2290096, 1, 1, 0, 2000),
|
||||
(8150302, 2290113, 1, 1, 0, 2000),
|
||||
(8150302, 2290119, 1, 1, 0, 2000),
|
||||
(8150302, 2290128, 1, 1, 0, 6000),
|
||||
(8160000, 2290017, 1, 1, 0, 2000),
|
||||
(8160000, 2290045, 1, 1, 0, 2000),
|
||||
(8160000, 2290065, 1, 1, 0, 2000),
|
||||
(8160000, 2290067, 1, 1, 0, 2000),
|
||||
(8160000, 2290081, 1, 1, 0, 2000),
|
||||
(8170000, 2290012, 1, 1, 0, 2000),
|
||||
(8170000, 2290086, 1, 1, 0, 2000),
|
||||
(8170000, 2290087, 1, 1, 0, 2000),
|
||||
(8170000, 2290134, 1, 1, 0, 6000),
|
||||
(8180000, 2290002, 1, 1, 0, 40000),
|
||||
(8180000, 2290003, 1, 1, 0, 40000),
|
||||
(8180000, 2290014, 1, 1, 0, 40000),
|
||||
(8180000, 2290015, 1, 1, 0, 40000),
|
||||
(8180000, 2290030, 1, 1, 0, 40000),
|
||||
(8180000, 2290035, 1, 1, 0, 40000),
|
||||
(8180000, 2290036, 1, 1, 0, 40000),
|
||||
(8180000, 2290063, 1, 1, 0, 40000),
|
||||
(8180000, 2290080, 1, 1, 0, 40000),
|
||||
(8180000, 2290098, 1, 1, 0, 40000),
|
||||
(8180000, 2290101, 1, 1, 0, 40000),
|
||||
(8180000, 2290117, 1, 1, 0, 40000),
|
||||
(8180000, 2290130, 1, 1, 0, 120000),
|
||||
(8180001, 2290018, 1, 1, 0, 40000),
|
||||
(8180001, 2290019, 1, 1, 0, 40000),
|
||||
(8180001, 2290032, 1, 1, 0, 40000),
|
||||
(8180001, 2290042, 1, 1, 0, 40000),
|
||||
(8180001, 2290058, 1, 1, 0, 40000),
|
||||
(8180001, 2290059, 1, 1, 0, 40000),
|
||||
(8180001, 2290068, 1, 1, 0, 40000),
|
||||
(8180001, 2290069, 1, 1, 0, 40000),
|
||||
(8180001, 2290072, 1, 1, 0, 40000),
|
||||
(8180001, 2290092, 1, 1, 0, 40000),
|
||||
(8180001, 2290099, 1, 1, 0, 40000),
|
||||
(8180001, 2290100, 1, 1, 0, 40000),
|
||||
(8180001, 2290102, 1, 1, 0, 40000),
|
||||
(8180001, 2290119, 1, 1, 0, 40000),
|
||||
(8180001, 2290128, 1, 1, 0, 120000),
|
||||
(8190000, 2280016, 1, 1, 0, 6000),
|
||||
(8190000, 2290030, 1, 1, 0, 2000),
|
||||
(8190000, 2290044, 1, 1, 0, 2000),
|
||||
(8190000, 2290054, 1, 1, 0, 2000),
|
||||
(8190000, 2290066, 1, 1, 0, 2000),
|
||||
(8190000, 2290075, 1, 1, 0, 2000),
|
||||
(8190000, 2290092, 1, 1, 0, 2000),
|
||||
(8190000, 2290103, 1, 1, 0, 2000),
|
||||
(8190002, 2290000, 1, 1, 0, 2000),
|
||||
(8190002, 2290008, 1, 1, 0, 2000),
|
||||
(8190002, 2290018, 1, 1, 0, 2000),
|
||||
(8190002, 2290038, 1, 1, 0, 2000),
|
||||
(8190002, 2290060, 1, 1, 0, 2000),
|
||||
(8190002, 2290080, 1, 1, 0, 2000),
|
||||
(8190002, 2290124, 1, 1, 0, 2000),
|
||||
(8190003, 2280013, 1, 1, 0, 6000),
|
||||
(8190003, 2290007, 1, 1, 0, 2000),
|
||||
(8190003, 2290012, 1, 1, 0, 2000),
|
||||
(8190003, 2290014, 1, 1, 0, 2000),
|
||||
(8190003, 2290033, 1, 1, 0, 2000),
|
||||
(8190003, 2290045, 1, 1, 0, 2000),
|
||||
(8190003, 2290050, 1, 1, 0, 2000),
|
||||
(8190003, 2290055, 1, 1, 0, 2000),
|
||||
(8190003, 2290062, 1, 1, 0, 2000),
|
||||
(8190003, 2290063, 1, 1, 0, 2000),
|
||||
(8190003, 2290070, 1, 1, 0, 2000),
|
||||
(8190003, 2290086, 1, 1, 0, 2000),
|
||||
(8190003, 2290108, 1, 1, 0, 2000),
|
||||
(8190003, 2290133, 1, 1, 0, 6000),
|
||||
(8190004, 2290002, 1, 1, 0, 2000),
|
||||
(8190004, 2290009, 1, 1, 0, 2000),
|
||||
(8190004, 2290021, 1, 1, 0, 2000),
|
||||
(8190004, 2290034, 1, 1, 0, 2000),
|
||||
(8190004, 2290041, 1, 1, 0, 2000),
|
||||
(8190004, 2290052, 1, 1, 0, 2000),
|
||||
(8190004, 2290053, 1, 1, 0, 2000),
|
||||
(8190004, 2290058, 1, 1, 0, 2000),
|
||||
(8190004, 2290068, 1, 1, 0, 2000),
|
||||
(8190004, 2290071, 1, 1, 0, 2000),
|
||||
(8190004, 2290073, 1, 1, 0, 2000),
|
||||
(8190004, 2290090, 1, 1, 0, 2000),
|
||||
(8190004, 2290112, 1, 1, 0, 2000),
|
||||
(8190004, 2290121, 1, 1, 0, 2000),
|
||||
(8190004, 2290130, 1, 1, 0, 6000),
|
||||
(8190005, 2290000, 1, 1, 0, 2000),
|
||||
(8190005, 2290008, 1, 1, 0, 2000),
|
||||
(8190005, 2290018, 1, 1, 0, 2000),
|
||||
(8190005, 2290038, 1, 1, 0, 2000),
|
||||
(8190005, 2290060, 1, 1, 0, 2000),
|
||||
(8190005, 2290080, 1, 1, 0, 2000),
|
||||
(8190005, 2290124, 1, 1, 0, 2000),
|
||||
(8200000, 2290005, 1, 1, 0, 2000),
|
||||
(8200000, 2290011, 1, 1, 0, 2000),
|
||||
(8200000, 2290114, 1, 1, 0, 2000),
|
||||
(8200001, 2280015, 1, 1, 0, 6000),
|
||||
(8200001, 2290050, 1, 1, 0, 2000),
|
||||
(8200001, 2290059, 1, 1, 0, 2000),
|
||||
(8200001, 2290065, 1, 1, 0, 2000),
|
||||
(8200001, 2290129, 1, 1, 0, 6000),
|
||||
(8200002, 2290062, 1, 1, 0, 2000),
|
||||
(8200002, 2290066, 1, 1, 0, 2000),
|
||||
(8200002, 2290070, 1, 1, 0, 2000),
|
||||
(8200002, 2290131, 1, 1, 0, 6000),
|
||||
(8200002, 2290139, 1, 1, 0, 6000),
|
||||
(8200003, 2290012, 1, 1, 0, 2000),
|
||||
(8200003, 2290056, 1, 1, 0, 2000),
|
||||
(8200003, 2290071, 1, 1, 0, 2000),
|
||||
(8200003, 2290101, 1, 1, 0, 2000),
|
||||
(8200003, 2290136, 1, 1, 0, 6000),
|
||||
(8200004, 2280016, 1, 1, 0, 6000),
|
||||
(8200004, 2290069, 1, 1, 0, 2000),
|
||||
(8200004, 2290072, 1, 1, 0, 2000),
|
||||
(8200004, 2290073, 1, 1, 0, 2000),
|
||||
(8200004, 2290127, 1, 1, 0, 6000),
|
||||
(8200004, 2290134, 1, 1, 0, 6000),
|
||||
(8200005, 2280014, 1, 1, 0, 6000),
|
||||
(8200005, 2290078, 1, 1, 0, 2000),
|
||||
(8200005, 2290079, 1, 1, 0, 2000),
|
||||
(8200005, 2290095, 1, 1, 0, 2000),
|
||||
(8200006, 2290003, 1, 1, 0, 2000),
|
||||
(8200006, 2290064, 1, 1, 0, 2000),
|
||||
(8200006, 2290076, 1, 1, 0, 2000),
|
||||
(8200006, 2290077, 1, 1, 0, 2000),
|
||||
(8200006, 2290129, 1, 1, 0, 6000),
|
||||
(8200006, 2290138, 1, 1, 0, 6000),
|
||||
(8200007, 2290006, 1, 1, 0, 2000),
|
||||
(8200007, 2290007, 1, 1, 0, 2000),
|
||||
(8200007, 2290011, 1, 1, 0, 2000),
|
||||
(8200007, 2290016, 1, 1, 0, 2000),
|
||||
(8200007, 2290125, 1, 1, 0, 2000),
|
||||
(8200007, 2290136, 1, 1, 0, 6000),
|
||||
(8200008, 2290006, 1, 1, 0, 2000),
|
||||
(8200008, 2290051, 1, 1, 0, 2000),
|
||||
(8200008, 2290121, 1, 1, 0, 2000),
|
||||
(8200008, 2290122, 1, 1, 0, 2000),
|
||||
(8200008, 2290133, 1, 1, 0, 6000),
|
||||
(8200009, 2290013, 1, 1, 0, 2000),
|
||||
(8200009, 2290016, 1, 1, 0, 2000),
|
||||
(8200009, 2290031, 1, 1, 0, 2000),
|
||||
(8200009, 2290039, 1, 1, 0, 2000),
|
||||
(8200010, 2290026, 1, 1, 0, 2000),
|
||||
(8200010, 2290059, 1, 1, 0, 2000),
|
||||
(8200010, 2290088, 1, 1, 0, 2000),
|
||||
(8200010, 2290089, 1, 1, 0, 2000),
|
||||
(8200010, 2290127, 1, 1, 0, 6000),
|
||||
(8200011, 2290001, 1, 1, 0, 3000),
|
||||
(8200011, 2290040, 1, 1, 0, 3000),
|
||||
(8200011, 2290046, 1, 1, 0, 3000),
|
||||
(8200011, 2290048, 1, 1, 0, 3000),
|
||||
(8200011, 2290049, 1, 1, 0, 3000),
|
||||
(8200011, 2290114, 1, 1, 0, 3000),
|
||||
(8200011, 2290137, 1, 1, 0, 9000),
|
||||
(8200012, 2290041, 1, 1, 0, 3000),
|
||||
(8200012, 2290092, 1, 1, 0, 3000),
|
||||
(8200012, 2290093, 1, 1, 0, 3000),
|
||||
(8200012, 2290115, 1, 1, 0, 3000),
|
||||
(8200012, 2290137, 1, 1, 0, 9000),
|
||||
(8200012, 2290139, 1, 1, 0, 9000),
|
||||
(8220002, 2290020, 1, 1, 0, 40000),
|
||||
(8220002, 2290081, 1, 1, 0, 40000),
|
||||
(8220002, 2290085, 1, 1, 0, 40000),
|
||||
(8220002, 2290133, 1, 1, 0, 120000),
|
||||
(8220003, 2290006, 1, 1, 0, 40000),
|
||||
(8220003, 2290030, 1, 1, 0, 40000),
|
||||
(8220003, 2290031, 1, 1, 0, 40000),
|
||||
(8220003, 2290032, 1, 1, 0, 40000),
|
||||
(8220003, 2290033, 1, 1, 0, 40000),
|
||||
(8220003, 2290060, 1, 1, 0, 40000),
|
||||
(8220003, 2290061, 1, 1, 0, 40000),
|
||||
(8220003, 2290076, 1, 1, 0, 40000),
|
||||
(8220003, 2290077, 1, 1, 0, 40000),
|
||||
(8220003, 2290104, 1, 1, 0, 40000),
|
||||
(8220003, 2290105, 1, 1, 0, 40000),
|
||||
(8220003, 2290117, 1, 1, 0, 40000),
|
||||
(8220003, 2290118, 1, 1, 0, 40000),
|
||||
(8220004, 2290018, 1, 1, 0, 40000),
|
||||
(8220004, 2290019, 1, 1, 0, 40000),
|
||||
(8220004, 2290024, 1, 1, 0, 40000),
|
||||
(8220004, 2290025, 1, 1, 0, 40000),
|
||||
(8220004, 2290058, 1, 1, 0, 40000),
|
||||
(8220004, 2290059, 1, 1, 0, 40000),
|
||||
(8220004, 2290076, 1, 1, 0, 40000),
|
||||
(8220004, 2290077, 1, 1, 0, 40000),
|
||||
(8220004, 2290106, 1, 1, 0, 40000),
|
||||
(8220004, 2290127, 1, 1, 0, 120000),
|
||||
(8220004, 2290134, 1, 1, 0, 120000),
|
||||
(8220005, 2290002, 1, 1, 0, 60000),
|
||||
(8220005, 2290003, 1, 1, 0, 60000),
|
||||
(8220005, 2290036, 1, 1, 0, 60000),
|
||||
(8220005, 2290037, 1, 1, 0, 60000),
|
||||
(8220005, 2290055, 1, 1, 0, 60000),
|
||||
(8220005, 2290080, 1, 1, 0, 60000),
|
||||
(8220005, 2290099, 1, 1, 0, 60000),
|
||||
(8220005, 2290131, 1, 1, 0, 180000),
|
||||
(8220005, 2290136, 1, 1, 0, 180000),
|
||||
(8220006, 2290012, 1, 1, 0, 80000),
|
||||
(8220006, 2290013, 1, 1, 0, 80000),
|
||||
(8220006, 2290042, 1, 1, 0, 80000),
|
||||
(8220006, 2290043, 1, 1, 0, 80000),
|
||||
(8220006, 2290060, 1, 1, 0, 80000),
|
||||
(8220006, 2290061, 1, 1, 0, 80000),
|
||||
(8220006, 2290090, 1, 1, 0, 80000),
|
||||
(8220006, 2290119, 1, 1, 0, 80000),
|
||||
(8220006, 2290120, 1, 1, 0, 80000),
|
||||
(8220006, 2290135, 1, 1, 0, 240000),
|
||||
(8220006, 2290138, 1, 1, 0, 240000),
|
||||
(8220007, 2290035, 1, 1, 0, 40000),
|
||||
(8220007, 2290091, 1, 1, 0, 40000),
|
||||
(8220007, 2290108, 1, 1, 0, 40000),
|
||||
(8220009, 2290031, 1, 1, 0, 40000),
|
||||
(8220009, 2290129, 1, 1, 0, 120000),
|
||||
(8220015, 2280004, 1, 1, 0, 40000),
|
||||
(8220015, 2280005, 1, 1, 0, 40000),
|
||||
(8220015, 2280006, 1, 1, 0, 40000),
|
||||
(8500002, 2280007, 1, 1, 0, 60000),
|
||||
(8500002, 2280008, 1, 1, 0, 60000),
|
||||
(8500002, 2280009, 1, 1, 0, 60000),
|
||||
(8500002, 2280010, 1, 1, 0, 60000),
|
||||
(8500002, 2290006, 1, 1, 0, 60000),
|
||||
(8500002, 2290010, 1, 1, 0, 60000),
|
||||
(8500002, 2290011, 1, 1, 0, 60000),
|
||||
(8500002, 2290013, 1, 1, 0, 60000),
|
||||
(8500002, 2290028, 1, 1, 0, 60000),
|
||||
(8500002, 2290037, 1, 1, 0, 60000),
|
||||
(8500002, 2290043, 1, 1, 0, 60000),
|
||||
(8500002, 2290051, 1, 1, 0, 60000),
|
||||
(8500002, 2290056, 1, 1, 0, 60000),
|
||||
(8500002, 2290061, 1, 1, 0, 60000),
|
||||
(8500002, 2290066, 1, 1, 0, 60000),
|
||||
(8500002, 2290071, 1, 1, 0, 60000),
|
||||
(8500002, 2290078, 1, 1, 0, 60000),
|
||||
(8500002, 2290089, 1, 1, 0, 60000),
|
||||
(8500002, 2290091, 1, 1, 0, 60000),
|
||||
(8500002, 2290104, 1, 1, 0, 60000),
|
||||
(8500002, 2290107, 1, 1, 0, 60000),
|
||||
(8500002, 2290121, 1, 1, 0, 60000),
|
||||
(8500002, 2290123, 1, 1, 0, 60000),
|
||||
(8500002, 2290126, 1, 1, 0, 180000),
|
||||
(8500002, 2290129, 1, 1, 0, 180000),
|
||||
(8510000, 2280007, 1, 1, 0, 40000),
|
||||
(8510000, 2280008, 1, 1, 0, 40000),
|
||||
(8510000, 2280009, 1, 1, 0, 40000),
|
||||
(8510000, 2280010, 1, 1, 0, 40000),
|
||||
(8510000, 2290000, 1, 1, 0, 40000),
|
||||
(8510000, 2290001, 1, 1, 0, 40000),
|
||||
(8510000, 2290004, 1, 1, 0, 40000),
|
||||
(8510000, 2290005, 1, 1, 0, 40000),
|
||||
(8510000, 2290024, 1, 1, 0, 40000),
|
||||
(8510000, 2290025, 1, 1, 0, 40000),
|
||||
(8510000, 2290026, 1, 1, 0, 40000),
|
||||
(8510000, 2290027, 1, 1, 0, 40000),
|
||||
(8510000, 2290052, 1, 1, 0, 40000),
|
||||
(8510000, 2290053, 1, 1, 0, 40000),
|
||||
(8510000, 2290054, 1, 1, 0, 40000),
|
||||
(8510000, 2290055, 1, 1, 0, 40000),
|
||||
(8510000, 2290076, 1, 1, 0, 40000),
|
||||
(8510000, 2290077, 1, 1, 0, 40000),
|
||||
(8510000, 2290082, 1, 1, 0, 40000),
|
||||
(8510000, 2290083, 1, 1, 0, 40000),
|
||||
(8510000, 2290097, 1, 1, 0, 40000),
|
||||
(8510000, 2290099, 1, 1, 0, 40000),
|
||||
(8510000, 2290106, 1, 1, 0, 40000),
|
||||
(8510000, 2290108, 1, 1, 0, 40000),
|
||||
(8510000, 2290112, 1, 1, 0, 40000),
|
||||
(8510000, 2290114, 1, 1, 0, 40000),
|
||||
(8510000, 2290122, 1, 1, 0, 40000),
|
||||
(8510000, 2290124, 1, 1, 0, 40000),
|
||||
(8510000, 2290132, 1, 1, 0, 120000),
|
||||
(8520000, 2280007, 1, 1, 0, 40000),
|
||||
(8520000, 2280008, 1, 1, 0, 40000),
|
||||
(8520000, 2280009, 1, 1, 0, 40000),
|
||||
(8520000, 2280010, 1, 1, 0, 40000),
|
||||
(8520000, 2290000, 1, 1, 0, 40000),
|
||||
(8520000, 2290001, 1, 1, 0, 40000),
|
||||
(8520000, 2290004, 1, 1, 0, 40000),
|
||||
(8520000, 2290005, 1, 1, 0, 40000),
|
||||
(8520000, 2290024, 1, 1, 0, 40000),
|
||||
(8520000, 2290025, 1, 1, 0, 40000),
|
||||
(8520000, 2290026, 1, 1, 0, 40000),
|
||||
(8520000, 2290027, 1, 1, 0, 40000),
|
||||
(8520000, 2290052, 1, 1, 0, 40000),
|
||||
(8520000, 2290053, 1, 1, 0, 40000),
|
||||
(8520000, 2290054, 1, 1, 0, 40000),
|
||||
(8520000, 2290055, 1, 1, 0, 40000),
|
||||
(8520000, 2290076, 1, 1, 0, 40000),
|
||||
(8520000, 2290077, 1, 1, 0, 40000),
|
||||
(8520000, 2290082, 1, 1, 0, 40000),
|
||||
(8520000, 2290083, 1, 1, 0, 40000),
|
||||
(8520000, 2290097, 1, 1, 0, 40000),
|
||||
(8520000, 2290099, 1, 1, 0, 40000),
|
||||
(8520000, 2290106, 1, 1, 0, 40000),
|
||||
(8520000, 2290108, 1, 1, 0, 40000),
|
||||
(8520000, 2290112, 1, 1, 0, 40000),
|
||||
(8520000, 2290114, 1, 1, 0, 40000),
|
||||
(8520000, 2290122, 1, 1, 0, 40000),
|
||||
(8520000, 2290124, 1, 1, 0, 40000),
|
||||
(8520000, 2290132, 1, 1, 0, 120000),
|
||||
(8800002, 2280007, 1, 1, 0, 80000),
|
||||
(8800002, 2280008, 1, 1, 0, 80000),
|
||||
(8800002, 2280009, 1, 1, 0, 80000),
|
||||
(8800002, 2280010, 1, 1, 0, 80000),
|
||||
(8800002, 2280013, 1, 1, 0, 240000),
|
||||
(8800002, 2280014, 1, 1, 0, 240000),
|
||||
(8800002, 2280015, 1, 1, 0, 240000),
|
||||
(8800002, 2280016, 1, 1, 0, 240000),
|
||||
(8800002, 2290006, 1, 1, 0, 80000),
|
||||
(8800002, 2290007, 1, 1, 0, 80000),
|
||||
(8800002, 2290016, 1, 1, 0, 80000),
|
||||
(8800002, 2290020, 1, 1, 0, 80000),
|
||||
(8800002, 2290022, 1, 1, 0, 80000),
|
||||
(8800002, 2290024, 1, 1, 0, 80000),
|
||||
(8800002, 2290028, 1, 1, 0, 80000),
|
||||
(8800002, 2290029, 1, 1, 0, 80000),
|
||||
(8800002, 2290040, 1, 1, 0, 80000),
|
||||
(8800002, 2290046, 1, 1, 0, 80000),
|
||||
(8800002, 2290048, 1, 1, 0, 80000),
|
||||
(8800002, 2290056, 1, 1, 0, 80000),
|
||||
(8800002, 2290057, 1, 1, 0, 80000),
|
||||
(8800002, 2290058, 1, 1, 0, 80000),
|
||||
(8800002, 2290064, 1, 1, 0, 80000),
|
||||
(8800002, 2290067, 1, 1, 0, 80000),
|
||||
(8800002, 2290074, 1, 1, 0, 80000),
|
||||
(8800002, 2290079, 1, 1, 0, 80000),
|
||||
(8800002, 2290084, 1, 1, 0, 80000),
|
||||
(8800002, 2290094, 1, 1, 0, 80000),
|
||||
(8800002, 2290110, 1, 1, 0, 80000),
|
||||
(8800002, 2290115, 1, 1, 0, 80000),
|
||||
(8810018, 2290017, 1, 1, 0, 100000),
|
||||
(8810018, 2290021, 1, 1, 0, 100000),
|
||||
(8810018, 2290023, 1, 1, 0, 100000),
|
||||
(8810018, 2290041, 1, 1, 0, 100000),
|
||||
(8810018, 2290047, 1, 1, 0, 100000),
|
||||
(8810018, 2290049, 1, 1, 0, 100000),
|
||||
(8810018, 2290065, 1, 1, 0, 100000),
|
||||
(8810018, 2290075, 1, 1, 0, 100000),
|
||||
(8810018, 2290085, 1, 1, 0, 100000),
|
||||
(8810018, 2290095, 1, 1, 0, 100000),
|
||||
(8810018, 2290096, 1, 1, 0, 100000),
|
||||
(8810018, 2290111, 1, 1, 0, 100000),
|
||||
(8810018, 2290116, 1, 1, 0, 100000),
|
||||
(8810018, 2290125, 1, 1, 0, 100000),
|
||||
(8810018, 2290133, 1, 1, 0, 300000),
|
||||
(8810018, 2290137, 1, 1, 0, 300000),
|
||||
(8810018, 2290139, 1, 1, 0, 300000),
|
||||
(8820000, 2290010, 1, 1, 0, 120000),
|
||||
(8820000, 2290022, 1, 1, 0, 120000),
|
||||
(8820000, 2290040, 1, 1, 0, 120000),
|
||||
(8820000, 2290046, 1, 1, 0, 120000),
|
||||
(8820000, 2290048, 1, 1, 0, 120000),
|
||||
(8820000, 2290052, 1, 1, 0, 120000),
|
||||
(8820000, 2290084, 1, 1, 0, 120000),
|
||||
(8820000, 2290090, 1, 1, 0, 120000),
|
||||
(8820000, 2290106, 1, 1, 0, 120000),
|
||||
(8820000, 2290119, 1, 1, 0, 120000),
|
||||
(8820001, 2290010, 1, 1, 0, 120000),
|
||||
(8820001, 2290022, 1, 1, 0, 120000),
|
||||
(8820001, 2290040, 1, 1, 0, 120000),
|
||||
(8820001, 2290046, 1, 1, 0, 120000),
|
||||
(8820001, 2290048, 1, 1, 0, 120000),
|
||||
(8820001, 2290052, 1, 1, 0, 120000),
|
||||
(8820001, 2290084, 1, 1, 0, 120000),
|
||||
(8820001, 2290090, 1, 1, 0, 120000),
|
||||
(8820001, 2290106, 1, 1, 0, 120000),
|
||||
(8820001, 2290119, 1, 1, 0, 120000),
|
||||
(9300028, 2280015, 1, 1, 0, 120000),
|
||||
(9300028, 2290026, 1, 1, 0, 40000),
|
||||
(9300028, 2290064, 1, 1, 0, 40000),
|
||||
(9300028, 2290075, 1, 1, 0, 40000),
|
||||
(9300028, 2290093, 1, 1, 0, 40000),
|
||||
(9300028, 2290111, 1, 1, 0, 40000),
|
||||
(9300094, 2280004, 1, 1, 0, 40000),
|
||||
(9300094, 2280005, 1, 1, 0, 40000),
|
||||
(9300094, 2280006, 1, 1, 0, 40000),
|
||||
(9300095, 2280004, 1, 1, 0, 2000),
|
||||
(9300095, 2280005, 1, 1, 0, 2000),
|
||||
(9300095, 2280006, 1, 1, 0, 2000),
|
||||
(9303016, 2290006, 1, 1, 0, 2000),
|
||||
(9303016, 2290030, 1, 1, 0, 2000),
|
||||
(9303016, 2290032, 1, 1, 0, 2000),
|
||||
(9303016, 2290060, 1, 1, 0, 2000),
|
||||
(9303016, 2290076, 1, 1, 0, 2000),
|
||||
(9303016, 2290104, 1, 1, 0, 2000),
|
||||
(9303016, 2290117, 1, 1, 0, 2000),
|
||||
(9400014, 2290053, 1, 1, 0, 40000),
|
||||
(9400014, 2290087, 1, 1, 0, 40000),
|
||||
(9400014, 2290112, 1, 1, 0, 40000),
|
||||
(9400014, 2290122, 1, 1, 0, 40000),
|
||||
(9400120, 2290045, 1, 1, 0, 40000),
|
||||
(9400121, 2280014, 1, 1, 0, 180000),
|
||||
(9400121, 2290081, 1, 1, 0, 60000),
|
||||
(9400121, 2290087, 1, 1, 0, 60000),
|
||||
(9400121, 2290101, 1, 1, 0, 60000),
|
||||
(9400121, 2290103, 1, 1, 0, 60000),
|
||||
(9400122, 2290007, 1, 1, 0, 40000),
|
||||
(9400122, 2290062, 1, 1, 0, 40000),
|
||||
(9400122, 2290116, 1, 1, 0, 40000),
|
||||
(9400300, 2290045, 1, 1, 0, 120000),
|
||||
(9400300, 2290055, 1, 1, 0, 120000),
|
||||
(9400300, 2290063, 1, 1, 0, 120000),
|
||||
(9400300, 2290079, 1, 1, 0, 120000),
|
||||
(9400300, 2290081, 1, 1, 0, 120000),
|
||||
(9400300, 2290096, 1, 1, 0, 120000),
|
||||
(9400514, 2290023, 1, 1, 0, 40000),
|
||||
(9400514, 2290057, 1, 1, 0, 40000),
|
||||
(9400514, 2290088, 1, 1, 0, 40000),
|
||||
(9400514, 2290095, 1, 1, 0, 40000),
|
||||
(9400514, 2290115, 1, 1, 0, 40000),
|
||||
(9400514, 2290139, 1, 1, 0, 120000),
|
||||
(9400549, 2290001, 1, 1, 0, 40000),
|
||||
(9400549, 2290020, 1, 1, 0, 40000),
|
||||
(9400549, 2290045, 1, 1, 0, 40000),
|
||||
(9400549, 2290057, 1, 1, 0, 40000),
|
||||
(9400549, 2290086, 1, 1, 0, 40000),
|
||||
(9400575, 2290009, 1, 1, 0, 40000),
|
||||
(9400575, 2290051, 1, 1, 0, 40000),
|
||||
(9400575, 2290081, 1, 1, 0, 40000),
|
||||
(9400575, 2290087, 1, 1, 0, 40000),
|
||||
(9400575, 2290107, 1, 1, 0, 40000),
|
||||
(9400575, 2290123, 1, 1, 0, 40000),
|
||||
(9400580, 2290004, 1, 1, 0, 2000),
|
||||
(9400580, 2290024, 1, 1, 0, 2000),
|
||||
(9400580, 2290083, 1, 1, 0, 2000),
|
||||
(9400580, 2290087, 1, 1, 0, 2000),
|
||||
(9400580, 2290103, 1, 1, 0, 2000),
|
||||
(9400580, 2290121, 1, 1, 0, 2000),
|
||||
(9400582, 2290005, 1, 1, 0, 2000),
|
||||
(9400582, 2290010, 1, 1, 0, 2000),
|
||||
(9400582, 2290029, 1, 1, 0, 2000),
|
||||
(9400582, 2290047, 1, 1, 0, 2000),
|
||||
(9400582, 2290049, 1, 1, 0, 2000),
|
||||
(9400582, 2290074, 1, 1, 0, 2000),
|
||||
(9400582, 2290079, 1, 1, 0, 2000),
|
||||
(9400582, 2290081, 1, 1, 0, 2000),
|
||||
(9400582, 2290135, 1, 1, 0, 6000),
|
||||
(9400590, 2290088, 1, 1, 0, 60000),
|
||||
(9400590, 2290125, 1, 1, 0, 60000),
|
||||
(9400590, 2290135, 1, 1, 0, 180000),
|
||||
(9400591, 2290039, 1, 1, 0, 60000),
|
||||
(9400591, 2290074, 1, 1, 0, 60000),
|
||||
(9400591, 2290113, 1, 1, 0, 60000),
|
||||
(9400592, 2290047, 1, 1, 0, 60000),
|
||||
(9400592, 2290123, 1, 1, 0, 60000),
|
||||
(9400592, 2290131, 1, 1, 0, 180000),
|
||||
(9400593, 2290069, 1, 1, 0, 60000),
|
||||
(9400593, 2290093, 1, 1, 0, 60000),
|
||||
(9400593, 2290138, 1, 1, 0, 180000),
|
||||
(9420513, 2290039, 1, 1, 0, 40000),
|
||||
(9420513, 2290100, 1, 1, 0, 40000),
|
||||
(9420513, 2290108, 1, 1, 0, 40000),
|
||||
(9420513, 2290118, 1, 1, 0, 40000),
|
||||
(9420513, 2290138, 1, 1, 0, 120000),
|
||||
(9420514, 2290099, 1, 1, 0, 1287),
|
||||
(9420517, 2290000, 1, 1, 0, 1287),
|
||||
(9420517, 2290008, 1, 1, 0, 1287),
|
||||
(9420517, 2290018, 1, 1, 0, 1287),
|
||||
(9420517, 2290038, 1, 1, 0, 1287),
|
||||
(9420517, 2290060, 1, 1, 0, 1287),
|
||||
(9420517, 2290080, 1, 1, 0, 1287),
|
||||
(9420517, 2290103, 1, 1, 0, 1287),
|
||||
(9420518, 2290123, 1, 1, 0, 1287),
|
||||
(9420519, 2290113, 1, 1, 0, 1287),
|
||||
(9420522, 2290000, 1, 1, 0, 1287),
|
||||
(9420522, 2290001, 1, 1, 0, 1287),
|
||||
(9420522, 2290011, 1, 1, 0, 1287),
|
||||
(9420522, 2290025, 1, 1, 0, 1287),
|
||||
(9420522, 2290028, 1, 1, 0, 1287),
|
||||
(9420522, 2290037, 1, 1, 0, 1287),
|
||||
(9420522, 2290043, 1, 1, 0, 1287),
|
||||
(9420522, 2290066, 1, 1, 0, 1287),
|
||||
(9420522, 2290082, 1, 1, 0, 1287),
|
||||
(9420522, 2290083, 1, 1, 0, 1287),
|
||||
(9420522, 2290089, 1, 1, 0, 1287),
|
||||
(9420522, 2290091, 1, 1, 0, 1287),
|
||||
(9420522, 2290107, 1, 1, 0, 1287),
|
||||
(9420540, 2280006, 1, 1, 0, 2000),
|
||||
(9420540, 2290119, 1, 1, 0, 2000),
|
||||
(9420540, 2290120, 1, 1, 0, 2000),
|
||||
(9420544, 2280007, 1, 1, 0, 80000),
|
||||
(9420544, 2280008, 1, 1, 0, 80000),
|
||||
(9420544, 2280009, 1, 1, 0, 80000),
|
||||
(9420544, 2280010, 1, 1, 0, 80000),
|
||||
(9420544, 2290002, 1, 1, 0, 80000),
|
||||
(9420544, 2290015, 1, 1, 0, 80000),
|
||||
(9420544, 2290022, 1, 1, 0, 80000),
|
||||
(9420544, 2290027, 1, 1, 0, 80000),
|
||||
(9420544, 2290034, 1, 1, 0, 80000),
|
||||
(9420544, 2290052, 1, 1, 0, 80000),
|
||||
(9420544, 2290054, 1, 1, 0, 80000),
|
||||
(9420544, 2290089, 1, 1, 0, 80000),
|
||||
(9420544, 2290094, 1, 1, 0, 80000),
|
||||
(9420544, 2290098, 1, 1, 0, 80000),
|
||||
(9420544, 2290105, 1, 1, 0, 80000),
|
||||
(9420544, 2290110, 1, 1, 0, 80000),
|
||||
(9420544, 2290119, 1, 1, 0, 80000),
|
||||
(9420549, 2280007, 1, 1, 0, 80000),
|
||||
(9420549, 2280008, 1, 1, 0, 80000),
|
||||
(9420549, 2280009, 1, 1, 0, 80000),
|
||||
(9420549, 2280010, 1, 1, 0, 80000),
|
||||
(9420549, 2290002, 1, 1, 0, 80000),
|
||||
(9420549, 2290015, 1, 1, 0, 80000),
|
||||
(9420549, 2290022, 1, 1, 0, 80000),
|
||||
(9420549, 2290027, 1, 1, 0, 80000),
|
||||
(9420549, 2290034, 1, 1, 0, 80000),
|
||||
(9420549, 2290052, 1, 1, 0, 80000),
|
||||
(9420549, 2290054, 1, 1, 0, 80000),
|
||||
(9420549, 2290089, 1, 1, 0, 80000),
|
||||
(9420549, 2290094, 1, 1, 0, 80000),
|
||||
(9420549, 2290098, 1, 1, 0, 80000),
|
||||
(9420549, 2290105, 1, 1, 0, 80000),
|
||||
(9420549, 2290110, 1, 1, 0, 80000),
|
||||
(9420549, 2290119, 1, 1, 0, 80000),
|
||||
(9500166, 2290044, 1, 1, 0, 2000),
|
||||
(9500173, 2290018, 1, 1, 0, 40000),
|
||||
(9500173, 2290019, 1, 1, 0, 40000),
|
||||
(9500173, 2290032, 1, 1, 0, 40000),
|
||||
(9500173, 2290042, 1, 1, 0, 40000),
|
||||
(9500173, 2290058, 1, 1, 0, 40000),
|
||||
(9500173, 2290068, 1, 1, 0, 40000),
|
||||
(9500173, 2290072, 1, 1, 0, 40000),
|
||||
(9500173, 2290092, 1, 1, 0, 40000),
|
||||
(9500173, 2290099, 1, 1, 0, 40000),
|
||||
(9500173, 2290102, 1, 1, 0, 40000),
|
||||
(9500173, 2290119, 1, 1, 0, 40000),
|
||||
(9500173, 2290128, 1, 1, 0, 120000),
|
||||
(9500174, 2290002, 1, 1, 0, 40000),
|
||||
(9500174, 2290014, 1, 1, 0, 40000),
|
||||
(9500174, 2290030, 1, 1, 0, 40000),
|
||||
(9500174, 2290080, 1, 1, 0, 40000),
|
||||
(9500174, 2290130, 1, 1, 0, 120000),
|
||||
(9500180, 2290010, 1, 1, 0, 40000),
|
||||
(9500180, 2290028, 1, 1, 0, 40000),
|
||||
(9500180, 2290126, 1, 1, 0, 120000),
|
||||
(9500181, 2290010, 1, 1, 0, 40000),
|
||||
(9500181, 2290028, 1, 1, 0, 40000),
|
||||
(9500181, 2290126, 1, 1, 0, 120000),
|
||||
(9500331, 2290010, 1, 1, 0, 40000),
|
||||
(9500331, 2290028, 1, 1, 0, 40000),
|
||||
(9500331, 2290126, 1, 1, 0, 120000),
|
||||
(9500332, 2290132, 1, 1, 0, 120000),
|
||||
(9500333, 2290006, 1, 1, 0, 40000),
|
||||
(9500333, 2290030, 1, 1, 0, 40000),
|
||||
(9500333, 2290032, 1, 1, 0, 40000),
|
||||
(9500333, 2290060, 1, 1, 0, 40000),
|
||||
(9500333, 2290076, 1, 1, 0, 40000),
|
||||
(9500333, 2290104, 1, 1, 0, 40000),
|
||||
(9500333, 2290117, 1, 1, 0, 40000);
|
||||
@@ -30,37 +30,35 @@ public enum MapleBuffStat {
|
||||
SHARP_EYES(0x20L),
|
||||
MANA_REFLECTION(0x40L),
|
||||
//ALWAYS_RIGHT(0X80L),
|
||||
|
||||
//------ bgn EDITED SLOT (was unused before) --------
|
||||
MAP_PROTECTION(0x100000000000000L),
|
||||
//------ end EDITED SLOT ----------------------------
|
||||
|
||||
SHADOW_CLAW(0x100L),
|
||||
INFINITY(0x200L),
|
||||
HOLY_SHIELD(0x400L),
|
||||
HAMSTRING(0x800L),
|
||||
BLIND(0x1000L),
|
||||
CONCENTRATE(0x2000L),
|
||||
HPREC(0x4000L),
|
||||
PUPPET(0x4000L),
|
||||
ECHO_OF_HERO(0x8000L),
|
||||
MPREC(0x10000L),
|
||||
MESO_UP_BY_ITEM(0x10000L),
|
||||
GHOST_MORPH(0x20000L),
|
||||
AURA(0x40000L),
|
||||
CONFUSE(0x80000L),
|
||||
ARIANT_PQ_SHIELD(0x40000L),
|
||||
|
||||
// ------ COUPON feature ------
|
||||
|
||||
COUPON_EXP1(0x100000L),
|
||||
COUPON_EXP2(0x200000L),
|
||||
COUPON_EXP3(0x400000L),
|
||||
COUPON_EXP4(0x800000L),
|
||||
COUPON_DRP1(0x1000000L),
|
||||
COUPON_DRP2(0x2000000L),
|
||||
COUPON_DRP3(0x4000000L),
|
||||
COUPON_EXP3(0x400000L), COUPON_EXP4(0x400000L),
|
||||
COUPON_DRP1(0x800000L),
|
||||
COUPON_DRP2(0x1000000L), COUPON_DRP3(0x1000000L),
|
||||
|
||||
// ---- end COUPON feature ----
|
||||
// ------ monster card buffs, thanks to Arnah (Vertisy) ------
|
||||
ITEM_UP_BY_ITEM(0x100000L),
|
||||
RESPECT_PIMMUNE(0x200000L),
|
||||
RESPECT_MIMMUNE(0x400000L),
|
||||
DEFENSE_ATT(0x800000L),
|
||||
DEFENSE_STATE(0x1000000L),
|
||||
|
||||
HPREC(0x2000000L),
|
||||
MPREC(0x4000000L),
|
||||
BERSERK_FURY(0x8000000L),
|
||||
DIVINE_BODY(0x10000000L),
|
||||
SPARK(0x20000000L),
|
||||
@@ -73,7 +71,6 @@ public enum MapleBuffStat {
|
||||
ACC(0x1000000000L),
|
||||
AVOID(0x2000000000L),
|
||||
HANDS(0x4000000000L),
|
||||
SHOWDASH(0x4000000000L),
|
||||
SPEED(0x8000000000L),
|
||||
JUMP(0x10000000000L),
|
||||
MAGIC_GUARD(0x20000000000L),
|
||||
@@ -96,11 +93,10 @@ public enum MapleBuffStat {
|
||||
MESOUP(0x200000000000000L),
|
||||
SHADOWPARTNER(0x400000000000000L),
|
||||
PICKPOCKET(0x800000000000000L),
|
||||
PUPPET(0x800000000000000L),
|
||||
MESOGUARD(0x1000000000000000L),
|
||||
EXP_INCREASE(0x2000000000000000L),
|
||||
WEAKEN(0x4000000000000000L),
|
||||
//THAT GAP
|
||||
MAP_PROTECTION(0x8000000000000000L),
|
||||
|
||||
//all incorrect buffstats
|
||||
SLOW(0x200000000L, true),
|
||||
@@ -144,4 +140,9 @@ public enum MapleBuffStat {
|
||||
public boolean isFirst() {
|
||||
return isFirst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
|
||||
+292
-111
@@ -44,6 +44,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.Comparator;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
@@ -205,7 +206,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
private transient int localstr, localdex, localluk, localint_, localmagic, localwatk;
|
||||
private transient int equipmaxhp, equipmaxmp, equipstr, equipdex, equipluk, equipint_, equipmagic, equipwatk, localchairhp, localchairmp;
|
||||
private int localchairrate;
|
||||
private boolean hidden, equipchanged = true, canDoor = true, berserk, hasMerchant, hasSandboxItem = false, whiteChat = false;
|
||||
private boolean hidden, equipchanged = true, canDoor = true, berserk, hasMerchant, hasSandboxItem = false, whiteChat = false, canRecvPartySearchInvite = true;
|
||||
private boolean equippedMesoMagnet = false, equippedItemPouch = false, equippedPetItemIgnore = false;
|
||||
private int linkedLevel = 0;
|
||||
private String linkedName = null;
|
||||
@@ -286,6 +287,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
private Lock cpnLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_CPN);
|
||||
private Map<Integer, Set<Integer>> excluded = new LinkedHashMap<>();
|
||||
private Set<Integer> excludedItems = new LinkedHashSet<>();
|
||||
private Set<Integer> disabledPartySearchInvites = new LinkedHashSet<>();
|
||||
private static String[] ariantroomleader = new String[3];
|
||||
private static int[] ariantroomslot = new int[3];
|
||||
private long portaldelay = 0, lastcombo = 0;
|
||||
@@ -484,6 +486,10 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
public void setEnteredChannelWorld() {
|
||||
awayFromWorld.set(false);
|
||||
client.getChannelServer().removePlayerAway(id);
|
||||
|
||||
if (canRecvPartySearchInvite) {
|
||||
this.getWorldServer().getPartySearchCoordinator().attachPlayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAwayFromChannelWorld() {
|
||||
@@ -504,6 +510,46 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePartySearchAvailability(boolean psearchAvailable) {
|
||||
if (psearchAvailable) {
|
||||
if (canRecvPartySearchInvite && getParty() == null) {
|
||||
this.getWorldServer().getPartySearchCoordinator().attachPlayer(this);
|
||||
}
|
||||
} else {
|
||||
if (canRecvPartySearchInvite) {
|
||||
this.getWorldServer().getPartySearchCoordinator().detachPlayer(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean toggleRecvPartySearchInvite() {
|
||||
canRecvPartySearchInvite = !canRecvPartySearchInvite;
|
||||
|
||||
if (canRecvPartySearchInvite) {
|
||||
updatePartySearchAvailability(getParty() == null);
|
||||
} else {
|
||||
this.getWorldServer().getPartySearchCoordinator().detachPlayer(this);
|
||||
}
|
||||
|
||||
return canRecvPartySearchInvite;
|
||||
}
|
||||
|
||||
public boolean isRecvPartySearchInviteEnabled() {
|
||||
return canRecvPartySearchInvite;
|
||||
}
|
||||
|
||||
public void resetPartySearchInvite(int fromLeaderid) {
|
||||
disabledPartySearchInvites.remove(fromLeaderid);
|
||||
}
|
||||
|
||||
public void disablePartySearchInvite(int fromLeaderid) {
|
||||
disabledPartySearchInvites.add(fromLeaderid);
|
||||
}
|
||||
|
||||
public boolean hasDisabledPartySearchInvite(int fromLeaderid) {
|
||||
return disabledPartySearchInvites.contains(fromLeaderid);
|
||||
}
|
||||
|
||||
public void setSessionTransitionState() {
|
||||
client.getSession().setAttribute(MapleClient.CLIENT_TRANSITION);
|
||||
}
|
||||
@@ -1047,7 +1093,13 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
return;//the fuck you doing idiot!
|
||||
}
|
||||
|
||||
this.job = newJob;
|
||||
if (canRecvPartySearchInvite && getParty() == null) {
|
||||
this.updatePartySearchAvailability(false);
|
||||
this.job = newJob;
|
||||
this.updatePartySearchAvailability(true);
|
||||
} else {
|
||||
this.job = newJob;
|
||||
}
|
||||
|
||||
int spGain = 1;
|
||||
if (GameConstants.hasSPTable(newJob)) {
|
||||
@@ -3448,6 +3500,10 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
for(Entry<Integer, Map<MapleBuffStat, MapleBuffStatValueHolder>> bpl: buffEffects.entrySet()) {
|
||||
MapleBuffStatValueHolder mbsvhi = bpl.getValue().get(mbs);
|
||||
if(mbsvhi != null) {
|
||||
if(!mbsvhi.effect.isActive(mapid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(mbsvhi.value > max.left) {
|
||||
max = new Pair<>(mbsvhi.value, mbsvhi.effect.getStatups().size());
|
||||
mbsvh = mbsvhi;
|
||||
@@ -3477,6 +3533,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
effLock.lock();
|
||||
chrLock.lock();
|
||||
try {
|
||||
System.out.println("-------------------");
|
||||
System.out.println("CACHED BUFF COUNT: ");
|
||||
for(Entry<MapleBuffStat, Byte> bpl : buffEffectsCount.entrySet()) {
|
||||
System.out.println(bpl.getKey() + ": " + bpl.getValue());
|
||||
}
|
||||
System.out.println("-------------------");
|
||||
System.out.println("CACHED BUFFS: ");
|
||||
for(Entry<Integer, Map<MapleBuffStat, MapleBuffStatValueHolder>> bpl : buffEffects.entrySet()) {
|
||||
@@ -3664,46 +3725,33 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateActiveEffects() {
|
||||
chrLock.lock();
|
||||
try {
|
||||
effects.clear();
|
||||
updateEffects(buffEffectsCount.keySet());
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEffects(Set<MapleBuffStat> removedStats) {
|
||||
chrLock.lock();
|
||||
try {
|
||||
Map<Integer, Pair<MapleStatEffect, Long>> retrievedEffects = new LinkedHashMap<>();
|
||||
Map<MapleBuffStat, Pair<Integer, Integer>> maxStatups = new LinkedHashMap<>();
|
||||
|
||||
for(Entry<Integer, Map<MapleBuffStat, MapleBuffStatValueHolder>> bel : buffEffects.entrySet()) {
|
||||
for(Entry<MapleBuffStat, MapleBuffStatValueHolder> belv : bel.getValue().entrySet()) {
|
||||
if(removedStats.contains(belv.getKey())) {
|
||||
if(!retrievedEffects.containsKey(bel.getKey())) {
|
||||
retrievedEffects.put(bel.getKey(), new Pair<>(belv.getValue().effect, belv.getValue().startTime));
|
||||
}
|
||||
|
||||
Pair<Integer, Integer> thisStat = maxStatups.get(belv.getKey());
|
||||
if(thisStat == null || belv.getValue().value > thisStat.getRight()) {
|
||||
maxStatups.put(belv.getKey(), new Pair<>(bel.getKey(), belv.getValue().value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, Pair<MapleStatEffect, Long>> bestEffects = new LinkedHashMap<>();
|
||||
Set<MapleBuffStat> retrievedStats = new LinkedHashSet<>();
|
||||
for(Entry<MapleBuffStat, Pair<Integer, Integer>> lmsee: maxStatups.entrySet()) {
|
||||
if(isSingletonStatup(lmsee.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer srcid = lmsee.getValue().getLeft();
|
||||
if(!bestEffects.containsKey(srcid)) {
|
||||
Pair<MapleStatEffect, Long> msel = retrievedEffects.get(srcid);
|
||||
for (MapleBuffStat mbs : removedStats) {
|
||||
fetchBestEffectFromItemEffectHolder(mbs);
|
||||
|
||||
bestEffects.put(srcid, msel);
|
||||
for(Pair<MapleBuffStat, Integer> mbsi : msel.getLeft().getStatups()) {
|
||||
retrievedStats.add(mbsi.getLeft());
|
||||
MapleBuffStatValueHolder mbsvh = effects.get(mbs);
|
||||
if (mbsvh != null) {
|
||||
for (Pair<MapleBuffStat, Integer> statup : mbsvh.effect.getStatups()) {
|
||||
retrievedStats.add(statup.getLeft());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
propagateBuffEffectUpdates(bestEffects, retrievedStats);
|
||||
propagateBuffEffectUpdates(new LinkedHashMap<Integer, Pair<MapleStatEffect, Long>>(), retrievedStats, removedStats);
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
@@ -3771,21 +3819,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
|
||||
if (!overwrite) {
|
||||
List<MapleBuffStat> cancelStats = new LinkedList<>();
|
||||
|
||||
chrLock.lock();
|
||||
try {
|
||||
for(Entry<MapleBuffStat, MapleBuffStatValueHolder> mbsl : buffstats.entrySet()) {
|
||||
cancelStats.add(mbsl.getKey());
|
||||
}
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
|
||||
for(MapleBuffStat mbs : cancelStats) {
|
||||
removedStats.add(mbs);
|
||||
}
|
||||
cancelPlayerBuffs(cancelStats);
|
||||
removedStats.addAll(buffstats.keySet());
|
||||
}
|
||||
|
||||
return toCancel;
|
||||
@@ -3909,7 +3943,152 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
return extractedStatBuffs;
|
||||
}
|
||||
|
||||
private void propagateBuffEffectUpdates(Map<Integer, Pair<MapleStatEffect, Long>> retrievedEffects, Set<MapleBuffStat> retrievedStats) {
|
||||
private void cancelInactiveBuffStats(Set<MapleBuffStat> retrievedStats, Set<MapleBuffStat> removedStats) {
|
||||
List<MapleBuffStat> inactiveStats = new LinkedList<>();
|
||||
for (MapleBuffStat mbs : removedStats) {
|
||||
if (!retrievedStats.contains(mbs)) {
|
||||
inactiveStats.add(mbs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!inactiveStats.isEmpty()) {
|
||||
client.announce(MaplePacketCreator.cancelBuff(inactiveStats));
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.cancelForeignBuff(getId(), inactiveStats), false);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<MapleStatEffect, Integer> topologicalSortLeafStatCount(Map<MapleBuffStat, Stack<MapleStatEffect>> buffStack) {
|
||||
Map<MapleStatEffect, Integer> leafBuffCount = new LinkedHashMap<>();
|
||||
|
||||
for (Entry<MapleBuffStat, Stack<MapleStatEffect>> e : buffStack.entrySet()) {
|
||||
Stack<MapleStatEffect> mseStack = e.getValue();
|
||||
if (mseStack.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MapleStatEffect mse = mseStack.peek();
|
||||
Integer count = leafBuffCount.get(mse);
|
||||
if (count == null) {
|
||||
leafBuffCount.put(mse, 1);
|
||||
} else {
|
||||
leafBuffCount.put(mse, count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return leafBuffCount;
|
||||
}
|
||||
|
||||
private static List<MapleStatEffect> topologicalSortRemoveLeafStats(Map<MapleStatEffect, Set<MapleBuffStat>> stackedBuffStats, Map<MapleBuffStat, Stack<MapleStatEffect>> buffStack, Map<MapleStatEffect, Integer> leafStatCount) {
|
||||
List<MapleStatEffect> clearedStatEffects = new LinkedList<>();
|
||||
Set<MapleBuffStat> clearedStats = new LinkedHashSet<>();
|
||||
|
||||
for (Entry<MapleStatEffect, Integer> e : leafStatCount.entrySet()) {
|
||||
MapleStatEffect mse = e.getKey();
|
||||
|
||||
if (stackedBuffStats.get(mse).size() <= e.getValue()) {
|
||||
clearedStatEffects.add(mse);
|
||||
|
||||
for (MapleBuffStat mbs : stackedBuffStats.get(mse)) {
|
||||
clearedStats.add(mbs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (MapleBuffStat mbs : clearedStats) {
|
||||
MapleStatEffect mse = buffStack.get(mbs).pop();
|
||||
stackedBuffStats.get(mse).remove(mbs);
|
||||
}
|
||||
|
||||
return clearedStatEffects;
|
||||
}
|
||||
|
||||
private static void topologicalSortRebaseLeafStats(Map<MapleStatEffect, Set<MapleBuffStat>> stackedBuffStats, Map<MapleBuffStat, Stack<MapleStatEffect>> buffStack) {
|
||||
for (Entry<MapleBuffStat, Stack<MapleStatEffect>> e : buffStack.entrySet()) {
|
||||
Stack<MapleStatEffect> mseStack = e.getValue();
|
||||
|
||||
if (!mseStack.isEmpty()) {
|
||||
MapleStatEffect mse = mseStack.pop();
|
||||
stackedBuffStats.get(mse).remove(e.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<MapleStatEffect> topologicalSortEffects(Map<MapleBuffStat, List<Pair<MapleStatEffect, Integer>>> buffEffects) {
|
||||
Map<MapleStatEffect, Set<MapleBuffStat>> stackedBuffStats = new LinkedHashMap<>();
|
||||
Map<MapleBuffStat, Stack<MapleStatEffect>> buffStack = new LinkedHashMap<>();
|
||||
|
||||
for (Entry<MapleBuffStat, List<Pair<MapleStatEffect, Integer>>> e : buffEffects.entrySet()) {
|
||||
MapleBuffStat mbs = e.getKey();
|
||||
|
||||
Stack<MapleStatEffect> mbsStack = new Stack<>();
|
||||
buffStack.put(mbs, mbsStack);
|
||||
|
||||
for (Pair<MapleStatEffect, Integer> emse : e.getValue()) {
|
||||
MapleStatEffect mse = emse.getLeft();
|
||||
mbsStack.push(mse);
|
||||
|
||||
Set<MapleBuffStat> mbsStats = stackedBuffStats.get(mse);
|
||||
if (mbsStats == null) {
|
||||
mbsStats = new LinkedHashSet<>();
|
||||
stackedBuffStats.put(mse, mbsStats);
|
||||
}
|
||||
|
||||
mbsStats.add(mbs);
|
||||
}
|
||||
}
|
||||
|
||||
List<MapleStatEffect> buffList = new LinkedList<>();
|
||||
while (true) {
|
||||
Map<MapleStatEffect, Integer> leafStatCount = topologicalSortLeafStatCount(buffStack);
|
||||
if (leafStatCount.isEmpty()) break;
|
||||
|
||||
List<MapleStatEffect> clearedNodes = topologicalSortRemoveLeafStats(stackedBuffStats, buffStack, leafStatCount);
|
||||
if (clearedNodes.isEmpty()) {
|
||||
topologicalSortRebaseLeafStats(stackedBuffStats, buffStack);
|
||||
} else {
|
||||
buffList.addAll(clearedNodes);
|
||||
}
|
||||
}
|
||||
|
||||
return buffList;
|
||||
}
|
||||
|
||||
private static List<MapleStatEffect> sortEffectsList(Map<MapleStatEffect, Integer> updateEffectsList) {
|
||||
Map<MapleBuffStat, List<Pair<MapleStatEffect, Integer>>> buffEffects = new LinkedHashMap<>();
|
||||
|
||||
for (Entry<MapleStatEffect, Integer> p : updateEffectsList.entrySet()) {
|
||||
MapleStatEffect mse = p.getKey();
|
||||
|
||||
for (Pair<MapleBuffStat, Integer> statup : mse.getStatups()) {
|
||||
MapleBuffStat stat = statup.getLeft();
|
||||
|
||||
List<Pair<MapleStatEffect, Integer>> statBuffs = buffEffects.get(stat);
|
||||
if (statBuffs == null) {
|
||||
statBuffs = new ArrayList<>();
|
||||
buffEffects.put(stat, statBuffs);
|
||||
}
|
||||
|
||||
statBuffs.add(new Pair<>(mse, statup.getRight()));
|
||||
}
|
||||
}
|
||||
|
||||
Comparator cmp = new Comparator<Pair<MapleStatEffect, Integer>>() {
|
||||
@Override
|
||||
public int compare(Pair<MapleStatEffect, Integer> o1, Pair<MapleStatEffect, Integer> o2)
|
||||
{
|
||||
return o2.getRight().compareTo(o1.getRight());
|
||||
}
|
||||
};
|
||||
|
||||
for (Entry<MapleBuffStat, List<Pair<MapleStatEffect, Integer>>> statBuffs : buffEffects.entrySet()) {
|
||||
Collections.sort(statBuffs.getValue(), cmp);
|
||||
}
|
||||
|
||||
return topologicalSortEffects(buffEffects);
|
||||
}
|
||||
|
||||
private void propagateBuffEffectUpdates(Map<Integer, Pair<MapleStatEffect, Long>> retrievedEffects, Set<MapleBuffStat> retrievedStats, Set<MapleBuffStat> removedStats) {
|
||||
cancelInactiveBuffStats(retrievedStats, removedStats);
|
||||
if (retrievedStats.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -3924,7 +4103,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
maxBuffValue.put(mbs, new Pair<>(Integer.MIN_VALUE, (MapleStatEffect) null));
|
||||
}
|
||||
|
||||
Map<MapleStatEffect, Pair<Integer, Integer>> updateEffects = new LinkedHashMap<>();
|
||||
Map<MapleStatEffect, Integer> updateEffects = new LinkedHashMap<>();
|
||||
|
||||
List<MapleStatEffect> recalcMseList = new LinkedList<>();
|
||||
for(Entry<Integer, Pair<MapleStatEffect, Long>> re : retrievedEffects.entrySet()) {
|
||||
@@ -3937,7 +4116,6 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
recalcMseList = new LinkedList<>();
|
||||
|
||||
for(MapleStatEffect mse : mseList) {
|
||||
int mseAmount = 0;
|
||||
int maxEffectiveStatup = Integer.MIN_VALUE;
|
||||
for(Pair<MapleBuffStat, Integer> st : mse.getStatups()) {
|
||||
MapleBuffStat mbs = st.getLeft();
|
||||
@@ -3972,36 +4150,16 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(relevantStatup) {
|
||||
mseAmount += st.getRight();
|
||||
}
|
||||
}
|
||||
|
||||
updateEffects.put(mse, new Pair<>(maxEffectiveStatup, mseAmount));
|
||||
updateEffects.put(mse, maxEffectiveStatup);
|
||||
}
|
||||
} while(!recalcMseList.isEmpty());
|
||||
|
||||
List<Pair<MapleStatEffect, Pair<Integer, Integer>>> updateEffectsList = new ArrayList<>();
|
||||
for(Entry<MapleStatEffect, Pair<Integer, Integer>> ue : updateEffects.entrySet()) {
|
||||
updateEffectsList.add(new Pair<>(ue.getKey(), ue.getValue()));
|
||||
}
|
||||
|
||||
Collections.sort(updateEffectsList, new Comparator<Pair<MapleStatEffect, Pair<Integer, Integer>>>() {
|
||||
@Override
|
||||
public int compare(Pair<MapleStatEffect, Pair<Integer, Integer>> o1, Pair<MapleStatEffect, Pair<Integer, Integer>> o2)
|
||||
{
|
||||
if(o1.getRight().getLeft().equals(o2.getRight().getLeft())) {
|
||||
return o1.getRight().getRight().compareTo(o2.getRight().getRight());
|
||||
} else {
|
||||
return o1.getRight().getLeft().compareTo(o2.getRight().getLeft());
|
||||
}
|
||||
}
|
||||
});
|
||||
List<MapleStatEffect> updateEffectsList = sortEffectsList(updateEffects);
|
||||
|
||||
List<Pair<Integer, Pair<MapleStatEffect, Long>>> toUpdateEffects = new LinkedList<>();
|
||||
for(Pair<MapleStatEffect, Pair<Integer, Integer>> msep : updateEffectsList) {
|
||||
MapleStatEffect mse = msep.getLeft();
|
||||
for(MapleStatEffect mse : updateEffectsList) {
|
||||
toUpdateEffects.add(new Pair<>(mse.getBuffSourceId(), retrievedEffects.get(mse.getBuffSourceId())));
|
||||
}
|
||||
|
||||
@@ -4010,9 +4168,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
Pair<MapleStatEffect, Long> msel = lmse.getRight();
|
||||
|
||||
for(Pair<MapleBuffStat, Integer> statup : getActiveStatupsFromSourceid(lmse.getLeft())) {
|
||||
if(!isSingletonStatup(statup.getLeft())) {
|
||||
activeStatups.add(statup);
|
||||
}
|
||||
activeStatups.add(statup);
|
||||
}
|
||||
|
||||
msel.getLeft().updateBuffEffect(this, activeStatups, msel.getRight());
|
||||
@@ -4061,6 +4217,17 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
}
|
||||
}
|
||||
|
||||
private void addItemEffectHolderCount(MapleBuffStat stat) {
|
||||
Byte val = buffEffectsCount.get(stat);
|
||||
if (val != null) {
|
||||
val = (byte) (val + 1);
|
||||
} else {
|
||||
val = (byte) 1;
|
||||
}
|
||||
|
||||
buffEffectsCount.put(stat, val);
|
||||
}
|
||||
|
||||
public void registerEffect(MapleStatEffect effect, long starttime, long expirationtime, boolean isSilent) {
|
||||
if (effect.isDragonBlood()) {
|
||||
prepareDragonBlood(effect);
|
||||
@@ -4180,6 +4347,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
appliedStatups.put(ps.getLeft(), new MapleBuffStatValueHolder(effect, starttime, ps.getRight()));
|
||||
}
|
||||
|
||||
boolean active = effect.isActive(mapid);
|
||||
if(ServerConstants.USE_BUFF_MOST_SIGNIFICANT) {
|
||||
toDeploy = new LinkedHashMap<>();
|
||||
Map<Integer, Pair<MapleStatEffect, Long>> retrievedEffects = new LinkedHashMap<>();
|
||||
@@ -4189,25 +4357,19 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
MapleBuffStatValueHolder mbsvh = effects.get(statup.getKey());
|
||||
MapleBuffStatValueHolder statMbsvh = statup.getValue();
|
||||
|
||||
if(mbsvh == null || mbsvh.value < statMbsvh.value || (mbsvh.value == statMbsvh.value && mbsvh.effect.getStatups().size() <= statMbsvh.effect.getStatups().size())) {
|
||||
toDeploy.put(statup.getKey(), statMbsvh);
|
||||
} else {
|
||||
if(!isSingletonStatup(statup.getKey())) {
|
||||
retrievedEffects.put(mbsvh.effect.getBuffSourceId(), new Pair<>(mbsvh.effect, mbsvh.startTime));
|
||||
for(Pair<MapleBuffStat, Integer> mbs : mbsvh.effect.getStatups()) {
|
||||
retrievedStats.add(mbs.getLeft());
|
||||
if(active) {
|
||||
if(mbsvh == null || mbsvh.value < statMbsvh.value || (mbsvh.value == statMbsvh.value && mbsvh.effect.getStatups().size() <= statMbsvh.effect.getStatups().size())) {
|
||||
toDeploy.put(statup.getKey(), statMbsvh);
|
||||
} else {
|
||||
if(!isSingletonStatup(statup.getKey())) {
|
||||
for(Pair<MapleBuffStat, Integer> mbs : mbsvh.effect.getStatups()) {
|
||||
retrievedStats.add(mbs.getLeft());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Byte val = buffEffectsCount.get(statup.getKey());
|
||||
if (val != null) {
|
||||
val = (byte) (val + 1);
|
||||
} else {
|
||||
val = (byte) 1;
|
||||
}
|
||||
|
||||
buffEffectsCount.put(statup.getKey(), val);
|
||||
addItemEffectHolderCount(statup.getKey());
|
||||
}
|
||||
|
||||
if(!isSilent) {
|
||||
@@ -4216,22 +4378,18 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
effects.put(statup.getKey(), statup.getValue());
|
||||
}
|
||||
|
||||
retrievedEffects.put(sourceid, new Pair<>(effect, starttime));
|
||||
propagateBuffEffectUpdates(retrievedEffects, retrievedStats);
|
||||
if (active) {
|
||||
retrievedEffects.put(sourceid, new Pair<>(effect, starttime));
|
||||
}
|
||||
|
||||
propagateBuffEffectUpdates(retrievedEffects, retrievedStats, new LinkedHashSet<MapleBuffStat>());
|
||||
}
|
||||
} else {
|
||||
for (Entry<MapleBuffStat, MapleBuffStatValueHolder> statup : appliedStatups.entrySet()) {
|
||||
Byte val = buffEffectsCount.get(statup.getKey());
|
||||
if (val != null) {
|
||||
val = (byte) (val + 1);
|
||||
} else {
|
||||
val = (byte) 1;
|
||||
}
|
||||
|
||||
buffEffectsCount.put(statup.getKey(), val);
|
||||
addItemEffectHolderCount(statup.getKey());
|
||||
}
|
||||
|
||||
toDeploy = appliedStatups;
|
||||
toDeploy = (active ? appliedStatups : new LinkedHashMap<MapleBuffStat, MapleBuffStatValueHolder>());
|
||||
}
|
||||
|
||||
addItemEffectHolder(sourceid, expirationtime, appliedStatups);
|
||||
@@ -4607,6 +4765,24 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
return w.getMesoRate() * w.getQuestRate();
|
||||
}
|
||||
|
||||
public float getCardRate(int itemid) {
|
||||
float rate = 100.0f;
|
||||
|
||||
if (itemid == 0) {
|
||||
MapleStatEffect mseMeso = getBuffEffect(MapleBuffStat.MESO_UP_BY_ITEM);
|
||||
if (mseMeso != null) {
|
||||
rate += mseMeso.getCardRate(mapid, itemid);
|
||||
}
|
||||
} else {
|
||||
MapleStatEffect mseItem = getBuffEffect(MapleBuffStat.ITEM_UP_BY_ITEM);
|
||||
if (mseItem != null) {
|
||||
rate += mseItem.getCardRate(mapid, itemid);
|
||||
}
|
||||
}
|
||||
|
||||
return rate / 100;
|
||||
}
|
||||
|
||||
public int getFace() {
|
||||
return face;
|
||||
}
|
||||
@@ -5169,6 +5345,13 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
this.gmLevel = Math.max(level, 0);
|
||||
}
|
||||
|
||||
public void closePartySearchInteractions() {
|
||||
this.getWorldServer().getPartySearchCoordinator().unregisterPartyLeader(this);
|
||||
if (canRecvPartySearchInvite) {
|
||||
this.getWorldServer().getPartySearchCoordinator().detachPlayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void closePlayerInteractions() {
|
||||
closeNpcShop();
|
||||
closeTrade();
|
||||
@@ -5570,8 +5753,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
return vanquisherStage;
|
||||
}
|
||||
|
||||
public Collection<MapleMapObject> getVisibleMapObjects() {
|
||||
return Collections.unmodifiableCollection(visibleMapObjects);
|
||||
public MapleMapObject[] getVisibleMapObjects() {
|
||||
return visibleMapObjects.toArray(new MapleMapObject[visibleMapObjects.size()]);
|
||||
}
|
||||
|
||||
public int getWorld() {
|
||||
@@ -6717,6 +6900,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
int buddyCapacity = rs.getInt("buddyCapacity");
|
||||
ret.buddylist = new BuddyList(buddyCapacity);
|
||||
ret.lastExpGainTime = rs.getTimestamp("lastExpGainTime").getTime();
|
||||
ret.canRecvPartySearchInvite = rs.getBoolean("partySearch");
|
||||
|
||||
ret.getInventory(MapleInventoryType.EQUIP).setSlotLimit(rs.getByte("equipslots"));
|
||||
ret.getInventory(MapleInventoryType.USE).setSlotLimit(rs.getByte("useslots"));
|
||||
@@ -7979,12 +8163,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
|
||||
con.setAutoCommit(false);
|
||||
PreparedStatement ps;
|
||||
ps = con.prepareStatement("UPDATE characters SET level = ?, fame = ?, str = ?, dex = ?, luk = ?, `int` = ?, exp = ?, gachaexp = ?, hp = ?, mp = ?, maxhp = ?, maxmp = ?, sp = ?, ap = ?, gm = ?, skincolor = ?, gender = ?, job = ?, hair = ?, face = ?, map = ?, meso = ?, hpMpUsed = ?, spawnpoint = ?, party = ?, buddyCapacity = ?, messengerid = ?, messengerposition = ?, mountlevel = ?, mountexp = ?, mounttiredness= ?, equipslots = ?, useslots = ?, setupslots = ?, etcslots = ?, monsterbookcover = ?, vanquisherStage = ?, dojoPoints = ?, lastDojoStage = ?, finishedDojoTutorial = ?, vanquisherKills = ?, matchcardwins = ?, matchcardlosses = ?, matchcardties = ?, omokwins = ?, omoklosses = ?, omokties = ?, dataString = ?, fquest = ?, jailexpire = ?, partnerId = ?, marriageItemId = ?, lastExpGainTime = ?, ariantPoints = ? WHERE id = ?", Statement.RETURN_GENERATED_KEYS);
|
||||
if (gmLevel < 1 && level > 199) {
|
||||
ps.setInt(1, isCygnus() ? 120 : 200);
|
||||
} else {
|
||||
ps.setInt(1, level);
|
||||
}
|
||||
ps = con.prepareStatement("UPDATE characters SET level = ?, fame = ?, str = ?, dex = ?, luk = ?, `int` = ?, exp = ?, gachaexp = ?, hp = ?, mp = ?, maxhp = ?, maxmp = ?, sp = ?, ap = ?, gm = ?, skincolor = ?, gender = ?, job = ?, hair = ?, face = ?, map = ?, meso = ?, hpMpUsed = ?, spawnpoint = ?, party = ?, buddyCapacity = ?, messengerid = ?, messengerposition = ?, mountlevel = ?, mountexp = ?, mounttiredness= ?, equipslots = ?, useslots = ?, setupslots = ?, etcslots = ?, monsterbookcover = ?, vanquisherStage = ?, dojoPoints = ?, lastDojoStage = ?, finishedDojoTutorial = ?, vanquisherKills = ?, matchcardwins = ?, matchcardlosses = ?, matchcardties = ?, omokwins = ?, omoklosses = ?, omokties = ?, dataString = ?, fquest = ?, jailexpire = ?, partnerId = ?, marriageItemId = ?, lastExpGainTime = ?, ariantPoints = ?, partySearch = ? WHERE id = ?", Statement.RETURN_GENERATED_KEYS);
|
||||
ps.setInt(1, level); // thanks CanIGetaPR for noticing an unnecessary "level" limitation when persisting DB data
|
||||
ps.setInt(2, fame);
|
||||
|
||||
effLock.lock();
|
||||
@@ -8094,7 +8274,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
|
||||
ps.setInt(52, marriageItemid);
|
||||
ps.setTimestamp(53, new Timestamp(lastExpGainTime));
|
||||
ps.setInt(54, ariantPoints);
|
||||
ps.setInt(55, id);
|
||||
ps.setBoolean(55, canRecvPartySearchInvite);
|
||||
ps.setInt(56, id);
|
||||
|
||||
int updateRows = ps.executeUpdate();
|
||||
ps.close();
|
||||
|
||||
@@ -888,6 +888,7 @@ public class MapleClient {
|
||||
player.cancelAllBuffs(true);
|
||||
|
||||
player.closePlayerInteractions();
|
||||
player.closePartySearchInteractions();
|
||||
|
||||
if (!serverTransition) { // thanks MedicOP for detecting an issue with party leader change on changing channels
|
||||
removePartyPlayer(wserv);
|
||||
@@ -1463,6 +1464,7 @@ public class MapleClient {
|
||||
}
|
||||
|
||||
player.closePlayerInteractions();
|
||||
player.closePartySearchInteractions();
|
||||
|
||||
player.unregisterChairBuff();
|
||||
server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs());
|
||||
|
||||
@@ -115,11 +115,6 @@ public enum MapleJob {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBeginner(MapleJob beginners) {
|
||||
return MAGICIAN == beginners || WARRIOR == beginners || THIEF == beginners || PIRATE == beginners || BOWMAN == beginners || ARAN1 == beginners || THUNDERBREAKER1 == beginners
|
||||
|| DAWNWARRIOR1 == beginners || NIGHTWALKER1 == beginners || BLAZEWIZARD1 == beginners;
|
||||
}
|
||||
|
||||
public boolean isA(MapleJob basejob) { // thanks Steve (kaito1410) for pointing out an improvement here
|
||||
int basebranch = basejob.getId() / 10;
|
||||
return (getId() / 10 == basebranch && getId() >= basejob.getId()) || (basebranch % 10 == 0 && getId() / 100 == basejob.getId() / 100);
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import server.ThreadManager;
|
||||
|
||||
public class IdCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class IdCommand extends Command {
|
||||
return;
|
||||
}
|
||||
final String queryItem = joinStringArr(Arrays.copyOfRange(params, 1, params.length), " ");
|
||||
player.yellowMessage("Querying for entry... May take some time... Please try to refine your search");
|
||||
player.yellowMessage("Querying for entry... May take some time... Please try to refine your search.");
|
||||
Runnable queryRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -42,28 +43,31 @@ public class IdCommand extends Command {
|
||||
populateIdMap(params[0].toLowerCase());
|
||||
|
||||
Map<String, String> resultList = fetchResults(itemMap.get(params[0]), queryItem);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (resultList.size() > 0) {
|
||||
int count = 0;
|
||||
for (Map.Entry<String, String> entry: resultList.entrySet()) {
|
||||
player.yellowMessage(String.format("Id for %s is: %s", entry.getKey(), entry.getValue()));
|
||||
sb.append(String.format("Id for %s is: #b%s#k", entry.getKey(), entry.getValue()) + "\r\n");
|
||||
if (++count > 100) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.yellowMessage(String.format("Results found: %d | Returned: %d/100 | Refine search query to improve time.", resultList.size(), count - 1));
|
||||
sb.append(String.format("Results found: #r%d#k | Returned: #b%d#k/100 | Refine search query to improve time.", resultList.size(), count) + "\r\n");
|
||||
|
||||
player.getClient().getAbstractPlayerInteraction().npcTalk(9010000, sb.toString());
|
||||
} else {
|
||||
player.yellowMessage(String.format("Id not found for item: %s, of type: %s", queryItem, params[0]));
|
||||
player.yellowMessage(String.format("Id not found for item: %s, of type: %s.", queryItem, params[0]));
|
||||
}
|
||||
} catch (IdTypeNotSupportedException e) {
|
||||
player.yellowMessage("Your query type is not supported");
|
||||
player.yellowMessage("Your query type is not supported.");
|
||||
} catch (IOException e) {
|
||||
player.yellowMessage("Error reading file, please contact your administrator");
|
||||
player.yellowMessage("Error reading file, please contact your administrator.");
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread thread = new Thread(queryRunnable);
|
||||
thread.start();
|
||||
|
||||
ThreadManager.getInstance().newTask(queryRunnable);
|
||||
}
|
||||
|
||||
private void populateIdMap(String type) throws IdTypeNotSupportedException, IOException {
|
||||
|
||||
@@ -39,10 +39,9 @@ import tools.MaplePacketCreator;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import tools.packets.Wedding;
|
||||
|
||||
public class DebugCommand extends Command {
|
||||
private final static String debugTypes[] = {"monster", "packet", "portal", "spawnpoint", "pos", "map", "mobsp", "event", "areas", "reactors", "servercoupons", "playercoupons", "timer", "marriage", ""};
|
||||
private final static String debugTypes[] = {"monster", "packet", "portal", "spawnpoint", "pos", "map", "mobsp", "event", "areas", "reactors", "servercoupons", "playercoupons", "timer", "marriage", "buff", ""};
|
||||
|
||||
{
|
||||
setDescription("");
|
||||
@@ -159,6 +158,9 @@ public class DebugCommand extends Command {
|
||||
c.getChannelServer().debugMarriageStatus();
|
||||
break;
|
||||
|
||||
case "buff":
|
||||
c.getPlayer().debugListAllBuffs();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,65 @@ public class MaplePet extends Item {
|
||||
}
|
||||
}
|
||||
|
||||
private static void unreferenceMissingPetsFromInventoryDb() {
|
||||
PreparedStatement ps = null;
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
|
||||
ps = con.prepareStatement("UPDATE inventoryitems SET petid = -1, expiration = 0 WHERE petid != -1 AND petid NOT IN (SELECT petid FROM pets)");
|
||||
ps.executeUpdate();
|
||||
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch(SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if(ps != null && !ps.isClosed()) {
|
||||
ps.close();
|
||||
}
|
||||
if(con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteMissingPetsFromDb() {
|
||||
PreparedStatement ps = null;
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
|
||||
ps = con.prepareStatement("DELETE FROM pets WHERE petid NOT IN (SELECT petid FROM inventoryitems WHERE petid != -1)");
|
||||
ps.executeUpdate();
|
||||
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch(SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if(ps != null && !ps.isClosed()) {
|
||||
ps.close();
|
||||
}
|
||||
if(con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearMissingPetsFromDb() {
|
||||
unreferenceMissingPetsFromInventoryDb();
|
||||
deleteMissingPetsFromDb();
|
||||
}
|
||||
|
||||
public static void deleteFromDb(MapleCharacter owner, int petid) {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
|
||||
@@ -439,7 +439,7 @@ public class MapleInventoryManipulator {
|
||||
announceModifyInventory(c, item, fromDrop, allowZero);
|
||||
}
|
||||
|
||||
MaplePet.deleteFromDb(chr, petid);
|
||||
// thanks Robin Schulz for noticing pet issues when moving pets out of inventory
|
||||
} else {
|
||||
inv.removeItem(slot, quantity, allowZero);
|
||||
if(type != MapleInventoryType.CANHOLD) {
|
||||
|
||||
@@ -75,11 +75,10 @@ public class ServerConstants {
|
||||
public static final boolean USE_FIXED_RATIO_HPMP_UPDATE = true; //Enables the HeavenMS-builtin HPMP update based on the current pool to max pool ratio.
|
||||
public static final boolean USE_FAMILY_SYSTEM = false;
|
||||
public static final boolean USE_DUEY = true;
|
||||
public static final boolean USE_RANDOMIZE_HPMP_GAIN = true; //Enables randomizing on MaxHP/MaxMP gains and INT accounting for the MaxMP gain.
|
||||
public static final boolean USE_RANDOMIZE_HPMP_GAIN = true; //Enables randomizing on MaxHP/MaxMP gains and INT accounting for the MaxMP gain on level up.
|
||||
public static final boolean USE_STORAGE_ITEM_SORT = true; //Enables storage "Arrange Items" feature.
|
||||
public static final boolean USE_ITEM_SORT = true; //Enables inventory "Item Sort/Merge" feature.
|
||||
public static final boolean USE_ITEM_SORT_BY_NAME = false; //Item sorting based on name rather than id.
|
||||
public static final boolean USE_PARTY_SEARCH = false;
|
||||
public static final boolean USE_PARTY_FOR_STARTERS = true; //Players level 10 or below can create/invite other players on the given level range.
|
||||
public static final boolean USE_AUTOASSIGN_STARTERS_AP = false; //Beginners level 10 or below have their AP autoassigned (they can't choose to levelup a stat). Set true ONLY if the localhost doesn't support AP assigning for beginners level 10 or below.
|
||||
public static final boolean USE_AUTOASSIGN_SECONDARY_CAP = true;//Prevents AP autoassign from spending on secondary stats after the player class' cap (defined on the autoassign handler) has been reached.
|
||||
@@ -95,8 +94,8 @@ public class ServerConstants {
|
||||
public static final boolean USE_ENFORCE_JOB_LEVEL_RANGE = false;//Caps the player level on the minimum required to advance their current jobs.
|
||||
public static final boolean USE_ENFORCE_JOB_SP_RANGE = false; //Caps the player SP level on the total obtainable by their current jobs. After changing jobs, missing SP will be retrieved.
|
||||
public static final boolean USE_ENFORCE_ITEM_SUGGESTION = false;//Forces the Owl of Minerva and the Cash Shop to always display the defined item array instead of those featured by the players.
|
||||
public static final boolean USE_ENFORCE_UNMERCHABLE_CASH = true;//Forces players to not sell CASH items via merchants.
|
||||
public static final boolean USE_ENFORCE_UNMERCHABLE_PET = true; //Forces players to not sell pets via merchants. (since non-named pets gets dirty name and other possible DB-related issues)
|
||||
public static final boolean USE_ENFORCE_UNMERCHABLE_CASH = false;//Forces players to not sell CASH items via merchants.
|
||||
public static final boolean USE_ENFORCE_UNMERCHABLE_PET = false; //Forces players to not sell pets via merchants. (since non-named pets gets dirty name and other possible DB-related issues)
|
||||
public static final boolean USE_ENFORCE_MERCHANT_SAVE = true; //Forces automatic DB save on merchant owners, at every item movement on shop.
|
||||
public static final boolean USE_ENFORCE_MDOOR_POSITION = false; //Forces mystic door to be spawned near spawnpoints.
|
||||
public static final boolean USE_SPAWN_LOOT_ON_ANIMATION = false;//Makes loot appear some time after the mob has been killed (following the mob death animation, instead of instantly).
|
||||
|
||||
@@ -36,7 +36,7 @@ public class Legend {
|
||||
public static final int MAKER = 20001007;
|
||||
public static final int BAMBOO_THRUST = 20001009;
|
||||
public static final int INVICIBLE_BARRIER = 20001010;
|
||||
public static final int POWER_EXPLOSION = 20011011;
|
||||
public static final int POWER_EXPLOSION = 20001011;
|
||||
public static final int METEO_SHOWER = 20001011;
|
||||
public static final int BLESSING_OF_THE_FAIRY = 20000012;
|
||||
public static final int TUTORIAL_SKILL1 = 20000014;
|
||||
|
||||
@@ -241,13 +241,13 @@ public final class PacketProcessor {
|
||||
registerHandler(RecvOpcode.ACCEPT_FAMILY, new AcceptFamilyHandler());
|
||||
registerHandler(RecvOpcode.DUEY_ACTION, new DueyHandler());
|
||||
registerHandler(RecvOpcode.USE_DEATHITEM, new UseDeathItemHandler());
|
||||
//registerHandler(RecvOpcode.PLAYER_UPDATE, new PlayerUpdateHandler()); unused
|
||||
registerHandler(RecvOpcode.PLAYER_MAP_TRANSFER, new PlayerMapTransitionHandler());
|
||||
registerHandler(RecvOpcode.USE_MAPLELIFE, new UseMapleLifeHandler());
|
||||
registerHandler(RecvOpcode.USE_CATCH_ITEM, new UseCatchItemHandler());
|
||||
registerHandler(RecvOpcode.MOB_DAMAGE_MOB_FRIENDLY, new MobDamageMobFriendlyHandler());
|
||||
registerHandler(RecvOpcode.PARTY_SEARCH_REGISTER, new PartySearchRegisterHandler());
|
||||
registerHandler(RecvOpcode.PARTY_SEARCH_START, new PartySearchStartHandler());
|
||||
registerHandler(RecvOpcode.PARTY_SEARCH_UPDATE, new PartySearchUpdateHandler());
|
||||
registerHandler(RecvOpcode.ITEM_SORT2, new InventorySortHandler());
|
||||
registerHandler(RecvOpcode.LEFT_KNOCKBACK, new LeftKnockbackHandler());
|
||||
registerHandler(RecvOpcode.SNOWBALL, new SnowballHandler());
|
||||
|
||||
@@ -186,7 +186,7 @@ public enum RecvOpcode {
|
||||
MONSTER_CARNIVAL(0xDA),
|
||||
PARTY_SEARCH_REGISTER(0xDC),
|
||||
PARTY_SEARCH_START(0xDE),
|
||||
PLAYER_UPDATE(0xDF),
|
||||
PARTY_SEARCH_UPDATE(0xDF),
|
||||
CHECK_CASH(0xE4),
|
||||
CASHSHOP_OPERATION(0xE5),
|
||||
COUPON_CODE(0xE6),
|
||||
|
||||
@@ -80,8 +80,10 @@ import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
|
||||
import client.MapleClient;
|
||||
import client.MapleCharacter;
|
||||
import client.SkillFactory;
|
||||
import client.command.CommandsExecutor;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.ItemFactory;
|
||||
import client.inventory.MaplePet;
|
||||
import client.inventory.manipulator.MapleCashidGenerator;
|
||||
import client.newyear.NewYearCardRecord;
|
||||
import constants.ItemConstants;
|
||||
@@ -838,33 +840,6 @@ public class Server {
|
||||
return rankSystem;
|
||||
}
|
||||
|
||||
private static void clearUnreferencedPetIds() {
|
||||
PreparedStatement ps = null;
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
|
||||
ps = con.prepareStatement("UPDATE inventoryitems SET petid = -1, expiration = 0 WHERE petid != -1 AND petid NOT IN (SELECT petid FROM pets)");
|
||||
ps.executeUpdate();
|
||||
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch(SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if(ps != null && !ps.isClosed()) {
|
||||
ps.close();
|
||||
}
|
||||
if(con != null && !con.isClosed()) {
|
||||
con.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
Properties p = loadWorldINI();
|
||||
if(p == null) {
|
||||
@@ -897,7 +872,7 @@ public class Server {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
|
||||
clearUnreferencedPetIds();
|
||||
MaplePet.clearMissingPetsFromDb();
|
||||
MapleCashidGenerator.loadExistentCashIdsFromDb();
|
||||
|
||||
IoBuffer.setUseDirectBuffer(false);
|
||||
@@ -971,6 +946,7 @@ public class Server {
|
||||
|
||||
MapleSkillbookInformationProvider.getInstance();
|
||||
OpcodeConstants.generateOpcodeNames();
|
||||
CommandsExecutor.getInstance();
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
||||
@@ -65,6 +65,7 @@ public enum MonitoredLockType {
|
||||
PARTY,
|
||||
WORLD_PARTY,
|
||||
WORLD_PARTY_SEARCH_ECHELON,
|
||||
WORLD_PARTY_SEARCH_QUEUE,
|
||||
WORLD_PARTY_SEARCH_STORAGE,
|
||||
WORLD_SRVMESSAGES,
|
||||
WORLD_PETS,
|
||||
|
||||
@@ -35,10 +35,15 @@ public final class DenyPartyRequestHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
slea.readByte();
|
||||
MapleCharacter cfrom = c.getChannelServer().getPlayerStorage().getCharacterByName(slea.readMapleAsciiString());
|
||||
String[] cname = slea.readMapleAsciiString().split("PS: ");
|
||||
|
||||
MapleCharacter cfrom = c.getChannelServer().getPlayerStorage().getCharacterByName(cname[cname.length - 1]);
|
||||
if (cfrom != null) {
|
||||
if (MapleInviteCoordinator.answerInvite(InviteType.PARTY, c.getPlayer().getId(), cfrom.getPartyId(), false).getLeft() == InviteResult.DENIED) {
|
||||
cfrom.getClient().announce(MaplePacketCreator.partyStatusMessage(23, c.getPlayer().getName()));
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
|
||||
if (MapleInviteCoordinator.answerInvite(InviteType.PARTY, chr.getId(), cfrom.getPartyId(), false).getLeft() == InviteResult.DENIED) {
|
||||
chr.updatePartySearchAvailability(chr.getParty() == null);
|
||||
cfrom.getClient().announce(MaplePacketCreator.partyStatusMessage(23, chr.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
mc.closePlayerInteractions();
|
||||
mc.closePartySearchInteractions();
|
||||
|
||||
mc.unregisterChairBuff();
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
|
||||
|
||||
@@ -87,6 +87,7 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
chr.closePlayerInteractions();
|
||||
chr.closePartySearchInteractions();
|
||||
|
||||
chr.unregisterChairBuff();
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
|
||||
|
||||
@@ -78,7 +78,8 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
|
||||
Set<MapleCharacter> eligibleMembers = new HashSet<>(MapleGuild.getEligiblePlayersForGuild(mc));
|
||||
if (eligibleMembers.size() < ServerConstants.CREATE_GUILD_MIN_PARTNERS) {
|
||||
if (mc.getMap().getAllPlayers().size() < ServerConstants.CREATE_GUILD_MIN_PARTNERS) {
|
||||
mc.dropMessage(1, "The Guild you are trying to create don't meet the minimum criteria of number of founders.");
|
||||
// thanks NovaStory for noticing message in need of smoother info
|
||||
mc.dropMessage(1, "Your Guild doesn't have enough cofounders present here and therefore cannot be created at this time.");
|
||||
} else {
|
||||
// players may be unaware of not belonging on a party in order to become eligible, thanks Hair (Legalize) for pointing this out
|
||||
mc.dropMessage(1, "Please make sure everyone you are trying to invite is neither on a guild nor on a party.");
|
||||
|
||||
@@ -56,6 +56,7 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler {
|
||||
List<MapleCharacter> partymembers = player.getPartyMembers();
|
||||
|
||||
MapleParty.leaveParty(party, c);
|
||||
player.updatePartySearchAvailability(true);
|
||||
player.partyOperationUpdate(party, partymembers);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -30,13 +30,7 @@ import client.MapleClient;
|
||||
* @author Quasar
|
||||
*/
|
||||
public class PartySearchRegisterHandler extends AbstractMaplePacketHandler {
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
return; //Disabling this for now.
|
||||
/* MapleCharacter chr = c.getPlayer();
|
||||
int min = slea.readInt();
|
||||
int max = slea.readInt();
|
||||
if (chr.getLevel() < min || chr.getLevel() > max || (max - min) > 30 || min > max) { // Client editing
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {}
|
||||
}
|
||||
@@ -21,108 +21,52 @@
|
||||
*/
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.world.MapleParty;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapObject;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import constants.ServerConstants;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import net.server.world.PartyOperation;
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author XoticStory
|
||||
* @author BubblesDev
|
||||
* @author Ronan
|
||||
*/
|
||||
public class PartySearchStartHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if(!ServerConstants.USE_PARTY_SEARCH){
|
||||
return;
|
||||
}
|
||||
int min = slea.readInt();
|
||||
int max = slea.readInt();
|
||||
|
||||
int min = slea.readInt();
|
||||
int max = slea.readInt();
|
||||
slea.readInt(); // members
|
||||
int jobs = slea.readInt();
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if (min > max) {
|
||||
chr.dropMessage(1, "The min. value is higher than the max!");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
MapleParty party = c.getPlayer().getParty();
|
||||
if(party == null) return;
|
||||
if (max - min > 30) {
|
||||
chr.dropMessage(1, "You can only search for party members within a range of 30 levels.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleMap map = chr.getMap();
|
||||
World world = c.getWorldServer();
|
||||
if (chr.getLevel() < min || chr.getLevel() > max) {
|
||||
chr.dropMessage(1, "The range of level for search has to include your own level.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<MapleMapObject> mapobjs = map.getPlayers();
|
||||
slea.readInt(); // members
|
||||
int jobs = slea.readInt();
|
||||
|
||||
for (MapleMapObject mapobj : mapobjs) {
|
||||
if (party.getMembers().size() > 5) {
|
||||
break;
|
||||
}
|
||||
if (mapobj instanceof MapleCharacter) {
|
||||
MapleCharacter tchar = (MapleCharacter) mapobj;
|
||||
int charlvl = tchar.getLevel();
|
||||
if (charlvl >= min && charlvl <= max && isValidJob(tchar.getJob(), jobs)) {
|
||||
if (tchar.getParty() == null) {
|
||||
MaplePartyCharacter partyplayer = new MaplePartyCharacter(tchar);
|
||||
tchar.getMap().addPartyMember(tchar);
|
||||
MapleParty party = c.getPlayer().getParty();
|
||||
if (party == null || !c.getPlayer().isPartyLeader()) return;
|
||||
|
||||
world.updateParty(party.getId(), PartyOperation.JOIN, partyplayer);
|
||||
tchar.receivePartyMemberHP();
|
||||
tchar.updatePartyMemberHP();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidJob(MapleJob thejob, int jobs) {
|
||||
int jobid = thejob.getId();
|
||||
if (jobid == 0) {
|
||||
return ((jobs & 2) > 0);
|
||||
} else if (jobid == 100) {
|
||||
return ((jobs & 4) > 0);
|
||||
} else if (jobid > 100 && jobid < 113) {
|
||||
return ((jobs & 8) > 0);
|
||||
} else if (jobid > 110 && jobid < 123) {
|
||||
return ((jobs & 16) > 0);
|
||||
} else if (jobid > 120 && jobid < 133) {
|
||||
return ((jobs & 32) > 0);
|
||||
} else if (jobid == 200) {
|
||||
return ((jobs & 64) > 0);
|
||||
} else if (jobid > 209 && jobid < 213) {
|
||||
return ((jobs & 128) > 0);
|
||||
} else if (jobid > 219 && jobid < 223) {
|
||||
return ((jobs & 256) > 0);
|
||||
} else if (jobid > 229 && jobid < 233) {
|
||||
return ((jobs & 512) > 0);
|
||||
} else if (jobid == 500) {
|
||||
return ((jobs & 1024) > 0);
|
||||
} else if (jobid > 509 && jobid < 513) {
|
||||
return ((jobs & 2048) > 0);
|
||||
} else if (jobid > 519 && jobid < 523) {
|
||||
return ((jobs & 4096) > 0);
|
||||
} else if (jobid == 400) {
|
||||
return ((jobs & 8192) > 0);
|
||||
} else if (jobid > 400 && jobid < 413) {
|
||||
return ((jobs & 16384) > 0);
|
||||
} else if (jobid > 419 && jobid < 423) {
|
||||
return ((jobs & 32768) > 0);
|
||||
} else if (jobid == 300) {
|
||||
return ((jobs & 65536) > 0);
|
||||
} else if (jobid > 300 && jobid < 313) {
|
||||
return ((jobs & 131072) > 0);
|
||||
} else if (jobid > 319 && jobid < 323) {
|
||||
return ((jobs & 262144) > 0);
|
||||
}
|
||||
return false;
|
||||
World world = c.getWorldServer();
|
||||
world.getPartySearchCoordinator().registerPartyLeader(chr, min, max, jobs);
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -25,8 +25,10 @@ import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public final class PlayerUpdateHandler extends AbstractMaplePacketHandler {
|
||||
public final class PartySearchUpdateHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {}
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
c.getWorldServer().getPartySearchCoordinator().unregisterPartyLeader(c.getPlayer());
|
||||
}
|
||||
}
|
||||
@@ -608,6 +608,8 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
MaplePlayerShop shop = chr.getPlayerShop();
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (shop != null && shop.isOwner(chr)) {
|
||||
System.out.println(shopItem.getItem().getPet() + " " + shopItem.getItem().getPetId());
|
||||
System.out.println(ivItem.getPet() + " " + ivItem.getPetId());
|
||||
if (shop.isOpen() || !shop.addItem(shopItem)) { // thanks Vcoc for pointing an exploit with unlimited shop slots
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "You can't sell it anymore."));
|
||||
return;
|
||||
|
||||
@@ -107,7 +107,7 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
|
||||
if (damage > 0) {
|
||||
loseItems = attacker.getStats().loseItem();
|
||||
if (loseItems != null) {
|
||||
if (chr.getBuffEffect(MapleBuffStat.ARIANT_PQ_SHIELD) == null) {
|
||||
if (chr.getBuffEffect(MapleBuffStat.AURA) == null) {
|
||||
MapleInventoryType type;
|
||||
final int playerpos = chr.getPosition().x;
|
||||
byte d = 1;
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
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 net.server.coordinator;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleJob;
|
||||
import constants.ServerConstants;
|
||||
import java.io.File;
|
||||
import net.server.world.MapleParty;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import net.server.coordinator.partysearch.PartySearchEchelon;
|
||||
import net.server.coordinator.partysearch.PartySearchStorage;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantReadWriteLock;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class MaplePartySearchCoordinator {
|
||||
|
||||
private Map<MapleJob, PartySearchStorage> storage = new HashMap<>();
|
||||
private Map<MapleJob, PartySearchEchelon> upcomers = new HashMap<>();
|
||||
|
||||
private List<MapleCharacter> leaderQueue = new LinkedList<>();
|
||||
private final ReentrantReadWriteLock leaderQueueLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.WORLD_PARTY_SEARCH_QUEUE, true);
|
||||
private final ReadLock leaderQueueRLock = leaderQueueLock.readLock();
|
||||
private final WriteLock leaderQueueWLock = leaderQueueLock.writeLock();
|
||||
|
||||
private Map<Integer, MapleCharacter> searchLeaders = new HashMap<>();
|
||||
private Map<Integer, LeaderSearchMetadata> searchSettings = new HashMap<>();
|
||||
|
||||
private static Map<Integer, Set<Integer>> mapNeighbors = fetchNeighbouringMaps();
|
||||
private static Map<Integer, MapleJob> jobTable = instantiateJobTable();
|
||||
|
||||
private static Map<Integer, Set<Integer>> fetchNeighbouringMaps() {
|
||||
Map<Integer, Set<Integer>> mapLinks = new HashMap<>();
|
||||
|
||||
MapleData data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/" + "Etc.wz")).getData("MapNeighbors.img");
|
||||
if (data != null) {
|
||||
for (MapleData mapdata : data.getChildren()) {
|
||||
int mapid = Integer.valueOf(mapdata.getName());
|
||||
|
||||
Set<Integer> neighborMaps = new HashSet<>();
|
||||
mapLinks.put(mapid, neighborMaps);
|
||||
|
||||
for (MapleData neighbordata : mapdata.getChildren()) {
|
||||
int neighborid = MapleDataTool.getInt(neighbordata, 999999999);
|
||||
|
||||
if (neighborid != 999999999) {
|
||||
neighborMaps.add(neighborid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mapLinks;
|
||||
}
|
||||
|
||||
public static boolean isInVicinity(int callerMapid, int calleeMapid) {
|
||||
Set<Integer> vicinityMapids = mapNeighbors.get(calleeMapid);
|
||||
|
||||
if (vicinityMapids != null) {
|
||||
return vicinityMapids.contains(calleeMapid);
|
||||
} else {
|
||||
int callerRange = callerMapid / 10000000;
|
||||
if (callerRange >= 90) {
|
||||
return callerRange == (calleeMapid / 1000000);
|
||||
} else {
|
||||
return callerRange == (calleeMapid / 10000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<Integer, MapleJob> instantiateJobTable() {
|
||||
Map<Integer, MapleJob> table = new HashMap<>();
|
||||
|
||||
List<Pair<Integer, Integer>> jobSearchTypes = new LinkedList<Pair<Integer, Integer>>() {{
|
||||
add(new Pair<>(MapleJob.MAPLELEAF_BRIGADIER.getId(), 0));
|
||||
add(new Pair<>(0, 0));
|
||||
add(new Pair<>(MapleJob.ARAN1.getId(), 0));
|
||||
add(new Pair<>(100, 3));
|
||||
add(new Pair<>(MapleJob.DAWNWARRIOR1.getId(), 0));
|
||||
add(new Pair<>(200, 3));
|
||||
add(new Pair<>(MapleJob.BLAZEWIZARD1.getId(), 0));
|
||||
add(new Pair<>(500, 2));
|
||||
add(new Pair<>(MapleJob.THUNDERBREAKER1.getId(), 0));
|
||||
add(new Pair<>(400, 2));
|
||||
add(new Pair<>(MapleJob.NIGHTWALKER1.getId(), 0));
|
||||
add(new Pair<>(300, 2));
|
||||
add(new Pair<>(MapleJob.WINDARCHER1.getId(), 0));
|
||||
add(new Pair<>(MapleJob.EVAN1.getId(), 0));
|
||||
}};
|
||||
|
||||
int i = 0;
|
||||
for (Pair<Integer, Integer> p : jobSearchTypes) {
|
||||
table.put(i, MapleJob.getById(p.getLeft()));
|
||||
i++;
|
||||
|
||||
for (int j = 1; j <= p.getRight(); j++) {
|
||||
table.put(i, MapleJob.getById(p.getLeft() + 10 * j));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private class LeaderSearchMetadata {
|
||||
private int minLevel;
|
||||
private int maxLevel;
|
||||
private List<MapleJob> searchedJobs;
|
||||
|
||||
private int reentryCount;
|
||||
|
||||
private List<MapleJob> decodeSearchedJobs(int jobsSelected) {
|
||||
List<MapleJob> searchedJobs = new LinkedList<>();
|
||||
|
||||
int topByte = (int)((Math.log(jobsSelected) / Math.log(2)) + 1e-5);
|
||||
|
||||
for (int i = 0; i <= topByte; i++) {
|
||||
if (jobsSelected % 2 == 1) {
|
||||
MapleJob job = jobTable.get(i);
|
||||
if (job != null) {
|
||||
searchedJobs.add(job);
|
||||
}
|
||||
}
|
||||
|
||||
jobsSelected = jobsSelected >> 1;
|
||||
if (jobsSelected == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return searchedJobs;
|
||||
}
|
||||
|
||||
private LeaderSearchMetadata(int minLevel, int maxLevel, int jobs) {
|
||||
this.minLevel = minLevel;
|
||||
this.maxLevel = maxLevel;
|
||||
this.searchedJobs = decodeSearchedJobs(jobs);
|
||||
this.reentryCount = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public MaplePartySearchCoordinator() {
|
||||
for (MapleJob job : jobTable.values()) {
|
||||
storage.put(job, new PartySearchStorage());
|
||||
upcomers.put(job, new PartySearchEchelon());
|
||||
}
|
||||
}
|
||||
|
||||
public void attachPlayer(MapleCharacter chr) {
|
||||
upcomers.get(getPartySearchJob(chr.getJob())).attachPlayer(chr);
|
||||
}
|
||||
|
||||
public void detachPlayer(MapleCharacter chr) {
|
||||
MapleJob psJob = getPartySearchJob(chr.getJob());
|
||||
|
||||
if (!upcomers.get(psJob).detachPlayer(chr)) {
|
||||
storage.get(psJob).detachPlayer(chr);
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePartySearchStorage() {
|
||||
for (Entry<MapleJob, PartySearchEchelon> psUpdate : upcomers.entrySet()) {
|
||||
storage.get(psUpdate.getKey()).updateStorage(psUpdate.getValue().exportEchelon());
|
||||
}
|
||||
}
|
||||
|
||||
private static MapleJob getPartySearchJob(MapleJob job) {
|
||||
if (job.getJobNiche() == 0) {
|
||||
return MapleJob.BEGINNER;
|
||||
} else if (job.getId() < 600) { // explorers
|
||||
return MapleJob.getById((job.getId() / 10) * 10);
|
||||
} else if (job.getId() >= 1000) {
|
||||
return MapleJob.getById((job.getId() / 100) * 100);
|
||||
} else {
|
||||
return MapleJob.MAPLELEAF_BRIGADIER;
|
||||
}
|
||||
}
|
||||
|
||||
private MapleCharacter fetchPlayer(int callerCid, int callerMapid, MapleJob job, int minLevel, int maxLevel) {
|
||||
return storage.get(getPartySearchJob(job)).callPlayer(callerCid, callerMapid, minLevel, maxLevel);
|
||||
}
|
||||
|
||||
private void addQueueLeader(MapleCharacter leader) {
|
||||
leaderQueueRLock.lock();
|
||||
try {
|
||||
leaderQueue.add(leader);
|
||||
} finally {
|
||||
leaderQueueRLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeQueueLeader(MapleCharacter leader) {
|
||||
leaderQueueRLock.lock();
|
||||
try {
|
||||
leaderQueue.remove(leader);
|
||||
} finally {
|
||||
leaderQueueRLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerPartyLeader(MapleCharacter leader, int minLevel, int maxLevel, int jobs) {
|
||||
if (searchLeaders.containsKey(leader.getId())) return;
|
||||
|
||||
searchSettings.put(leader.getId(), new LeaderSearchMetadata(minLevel, maxLevel, jobs));
|
||||
searchLeaders.put(leader.getId(), leader);
|
||||
addQueueLeader(leader);
|
||||
}
|
||||
|
||||
public void unregisterPartyLeader(MapleCharacter leader) {
|
||||
MapleCharacter toRemove = searchLeaders.remove(leader.getId());
|
||||
if (toRemove != null) {
|
||||
removeQueueLeader(toRemove);
|
||||
searchSettings.remove(leader.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private MapleCharacter searchPlayer(MapleCharacter leader) {
|
||||
LeaderSearchMetadata settings = searchSettings.get(leader.getId());
|
||||
if (settings != null) {
|
||||
int minLevel = settings.minLevel, maxLevel = settings.maxLevel;
|
||||
Collections.shuffle(settings.searchedJobs);
|
||||
|
||||
int leaderCid = leader.getId();
|
||||
int leaderMapid = leader.getMapId();
|
||||
for (MapleJob searchJob : settings.searchedJobs) {
|
||||
MapleCharacter chr = fetchPlayer(leaderCid, leaderMapid, searchJob, minLevel, maxLevel);
|
||||
if (chr != null) {
|
||||
return chr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean sendPartyInviteFromSearch(MapleCharacter chr, MapleCharacter leader) {
|
||||
if (chr == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int partyid = leader.getPartyId();
|
||||
if (partyid < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MapleInviteCoordinator.createInvite(InviteType.PARTY, leader, partyid, chr.getId())) {
|
||||
chr.disablePartySearchInvite(leader.getId());
|
||||
chr.announce(MaplePacketCreator.partySearchInvite(leader));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<List<MapleCharacter>, List<MapleCharacter>> fetchQueuedLeaders() {
|
||||
List<MapleCharacter> queuedLeaders, nextLeaders;
|
||||
|
||||
leaderQueueWLock.lock();
|
||||
try {
|
||||
int splitIdx = Math.min(leaderQueue.size(), 100);
|
||||
|
||||
queuedLeaders = new LinkedList<>(leaderQueue.subList(0, splitIdx));
|
||||
nextLeaders = new LinkedList<>(leaderQueue.subList(splitIdx, leaderQueue.size()));
|
||||
} finally {
|
||||
leaderQueueWLock.unlock();
|
||||
}
|
||||
|
||||
return new Pair<>(queuedLeaders, nextLeaders);
|
||||
}
|
||||
|
||||
public void runPartySearch() {
|
||||
Pair<List<MapleCharacter>, List<MapleCharacter>> queuedLeaders = fetchQueuedLeaders();
|
||||
|
||||
List<MapleCharacter> searchedLeaders = new LinkedList<>();
|
||||
List<MapleCharacter> recalledLeaders = new LinkedList<>();
|
||||
List<MapleCharacter> expiredLeaders = new LinkedList<>();
|
||||
|
||||
for (MapleCharacter leader : queuedLeaders.getLeft()) {
|
||||
MapleCharacter chr = searchPlayer(leader);
|
||||
if (sendPartyInviteFromSearch(chr, leader)) {
|
||||
searchedLeaders.add(leader);
|
||||
} else {
|
||||
LeaderSearchMetadata settings = searchSettings.get(leader.getId());
|
||||
if (settings != null) {
|
||||
if (settings.reentryCount < ServerConstants.PARTY_SEARCH_REENTRY_LIMIT) {
|
||||
settings.reentryCount += 1;
|
||||
recalledLeaders.add(leader);
|
||||
} else {
|
||||
expiredLeaders.add(leader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leaderQueueRLock.lock();
|
||||
try {
|
||||
leaderQueue.clear();
|
||||
leaderQueue.addAll(queuedLeaders.getRight());
|
||||
|
||||
try {
|
||||
leaderQueue.addAll(25, recalledLeaders);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
leaderQueue.addAll(recalledLeaders);
|
||||
}
|
||||
} finally {
|
||||
leaderQueueRLock.unlock();
|
||||
}
|
||||
|
||||
for (MapleCharacter leader : searchedLeaders) {
|
||||
MapleParty party = leader.getParty();
|
||||
if (party != null && party.getMembers().size() < 6) {
|
||||
addQueueLeader(leader);
|
||||
} else {
|
||||
if (leader.isLoggedinWorld()) leader.dropMessage(5, "Your Party Search token session has finished as your party reached full capacity.");
|
||||
searchLeaders.remove(leader.getId());
|
||||
searchSettings.remove(leader.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (MapleCharacter leader : expiredLeaders) {
|
||||
if (leader.isLoggedinWorld()) leader.dropMessage(5, "Your Party Search token session expired, please stop your Party Search and retry again later.");
|
||||
searchLeaders.remove(leader.getId());
|
||||
searchSettings.remove(leader.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
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 net.server.coordinator.partysearch;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import net.server.coordinator.MaplePartySearchCoordinator;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class PartySearchCharacter {
|
||||
|
||||
private WeakReference<MapleCharacter> player;
|
||||
private int level;
|
||||
private boolean queued;
|
||||
|
||||
public PartySearchCharacter(MapleCharacter chr) {
|
||||
player = new WeakReference(chr);
|
||||
level = chr.getLevel();
|
||||
queued = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
MapleCharacter chr = player.get();
|
||||
return chr == null ? "[empty]" : chr.toString();
|
||||
}
|
||||
|
||||
public MapleCharacter callPlayer(int leaderid, int callerMapid) {
|
||||
MapleCharacter chr = player.get();
|
||||
if (chr == null || !MaplePartySearchCoordinator.isInVicinity(callerMapid, chr.getMapId())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (chr.hasDisabledPartySearchInvite(leaderid)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
queued = false;
|
||||
if (chr.isLoggedinWorld() && chr.getParty() == null) {
|
||||
return chr;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public MapleCharacter getPlayer() {
|
||||
return player.get();
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public boolean isQueued() {
|
||||
return queued;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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 net.server.coordinator.partysearch;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantReadWriteLock;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class PartySearchEchelon {
|
||||
|
||||
private final ReentrantReadWriteLock psLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.WORLD_PARTY_SEARCH_ECHELON, true);
|
||||
private final ReadLock psRLock = psLock.readLock();
|
||||
private final WriteLock psWLock = psLock.writeLock();
|
||||
|
||||
private Map<Integer, WeakReference<MapleCharacter>> echelon = new HashMap<>(20);
|
||||
|
||||
public List<MapleCharacter> exportEchelon() {
|
||||
psWLock.lock(); // reversing read/write actually could provide a lax yet sure performance/precision trade-off here
|
||||
try {
|
||||
List<MapleCharacter> players = new ArrayList<>(echelon.size());
|
||||
|
||||
for (WeakReference<MapleCharacter> chrRef : echelon.values()) {
|
||||
MapleCharacter chr = chrRef.get();
|
||||
if (chr != null) {
|
||||
players.add(chr);
|
||||
}
|
||||
}
|
||||
|
||||
echelon.clear();
|
||||
return players;
|
||||
} finally {
|
||||
psWLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void attachPlayer(MapleCharacter chr) {
|
||||
psRLock.lock();
|
||||
try {
|
||||
echelon.put(chr.getId(), new WeakReference<>(chr));
|
||||
} finally {
|
||||
psRLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean detachPlayer(MapleCharacter chr) {
|
||||
psRLock.lock();
|
||||
try {
|
||||
return echelon.remove(chr.getId()) != null;
|
||||
} finally {
|
||||
psRLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
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 net.server.coordinator.partysearch;
|
||||
|
||||
import client.MapleCharacter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantReadWriteLock;
|
||||
|
||||
import java.awt.geom.Line2D;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class PartySearchStorage {
|
||||
|
||||
private List<PartySearchCharacter> storage = new ArrayList<>(20);
|
||||
private PartySearchEmptyIntervals emptyManager = new PartySearchEmptyIntervals();
|
||||
|
||||
private class PartySearchEmptyIntervals {
|
||||
|
||||
private List<Line2D> emptyLimits = new ArrayList<>();
|
||||
|
||||
private void refitEmptyIntervals(int st, int en, int minLevel, int maxLevel) {
|
||||
List<Line2D> checkLimits = new ArrayList<>(emptyLimits.subList(st, en));
|
||||
|
||||
float newLimitX1, newLimitX2;
|
||||
if (!checkLimits.isEmpty()) {
|
||||
Line2D firstLimit = checkLimits.get(0);
|
||||
Line2D lastLimit = checkLimits.get(checkLimits.size() - 1);
|
||||
|
||||
newLimitX1 = (float) ((minLevel < firstLimit.getX1()) ? minLevel : firstLimit.getX1());
|
||||
newLimitX2 = (float) ((maxLevel > lastLimit.getX2()) ? maxLevel : lastLimit.getX2());
|
||||
|
||||
for (Line2D limit : checkLimits) {
|
||||
emptyLimits.remove(st);
|
||||
}
|
||||
} else {
|
||||
newLimitX1 = minLevel;
|
||||
newLimitX2 = maxLevel;
|
||||
}
|
||||
|
||||
emptyLimits.add(st, new Line2D.Float((float) newLimitX1, 0, (float) newLimitX2, 0));
|
||||
}
|
||||
|
||||
private int bsearchInterval(int level) {
|
||||
int st = 0, en = emptyLimits.size() - 1;
|
||||
|
||||
int mid, idx;
|
||||
while (en >= st) {
|
||||
idx = (st + en) / 2;
|
||||
mid = (int) emptyLimits.get(idx).getX1();
|
||||
|
||||
if (mid == level) {
|
||||
return idx;
|
||||
} else if (mid < level) {
|
||||
st = idx + 1;
|
||||
} else {
|
||||
en = idx - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return en;
|
||||
}
|
||||
|
||||
public void addEmptyInterval(int fromLevel, int toLevel) {
|
||||
synchronized (emptyLimits) { // adding intervals occurs on a same-thread process, so this is actually not performance grinding
|
||||
int st = bsearchInterval(fromLevel);
|
||||
if (st < 0) {
|
||||
st = 0;
|
||||
} else if (emptyLimits.get(st).getX2() < fromLevel) {
|
||||
st += 1;
|
||||
}
|
||||
|
||||
int en = bsearchInterval(toLevel);
|
||||
if (en < st) en = st - 1;
|
||||
|
||||
refitEmptyIntervals(st, en + 1, fromLevel, toLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInEmptyInterval(int minLevel, int maxLevel) {
|
||||
synchronized (emptyLimits) {
|
||||
int idx = bsearchInterval(minLevel);
|
||||
return idx >= 0 && maxLevel <= emptyLimits.get(idx).getX2();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearEmptyInterval() {
|
||||
synchronized (emptyLimits) {
|
||||
emptyLimits.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final ReentrantReadWriteLock psLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.WORLD_PARTY_SEARCH_STORAGE, true);
|
||||
private final ReadLock psRLock = psLock.readLock();
|
||||
private final WriteLock psWLock = psLock.writeLock();
|
||||
|
||||
public List<PartySearchCharacter> getStorageList() {
|
||||
psRLock.lock();
|
||||
try {
|
||||
return new ArrayList<>(storage);
|
||||
} finally {
|
||||
psRLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Integer, MapleCharacter> fetchRemainingPlayers() {
|
||||
List<PartySearchCharacter> players = getStorageList();
|
||||
Map<Integer, MapleCharacter> remainingPlayers = new HashMap<>(players.size());
|
||||
|
||||
for (PartySearchCharacter psc : players) {
|
||||
if (psc.isQueued()) {
|
||||
MapleCharacter chr = psc.getPlayer();
|
||||
if (chr != null) {
|
||||
remainingPlayers.put(chr.getId(), chr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return remainingPlayers;
|
||||
}
|
||||
|
||||
public void updateStorage(Collection<MapleCharacter> echelon) {
|
||||
Map<Integer, MapleCharacter> newcomers = new HashMap<>();
|
||||
for (MapleCharacter chr : echelon) {
|
||||
newcomers.put(chr.getId(), chr);
|
||||
}
|
||||
|
||||
Map<Integer, MapleCharacter> curStorage = fetchRemainingPlayers();
|
||||
curStorage.putAll(newcomers);
|
||||
|
||||
List<PartySearchCharacter> pscList = new ArrayList<>(curStorage.size());
|
||||
for (MapleCharacter chr : curStorage.values()) {
|
||||
pscList.add(new PartySearchCharacter(chr));
|
||||
}
|
||||
|
||||
Collections.sort(pscList, new Comparator<PartySearchCharacter>() {
|
||||
@Override
|
||||
public int compare(PartySearchCharacter c1, PartySearchCharacter c2)
|
||||
{
|
||||
int levelP1 = c1.getLevel(), levelP2 = c2.getLevel();
|
||||
return levelP1 > levelP2 ? 1 : (levelP1 == levelP2 ? 0 : -1);
|
||||
}
|
||||
});
|
||||
|
||||
psWLock.lock();
|
||||
try {
|
||||
storage.clear();
|
||||
storage.addAll(pscList);
|
||||
} finally {
|
||||
psWLock.unlock();
|
||||
}
|
||||
|
||||
emptyManager.clearEmptyInterval();
|
||||
}
|
||||
|
||||
private static int bsearchStorage(List<PartySearchCharacter> storage, int level) {
|
||||
int st = 0, en = storage.size() - 1;
|
||||
|
||||
int mid, idx;
|
||||
while (en >= st) {
|
||||
idx = (st + en) / 2;
|
||||
mid = storage.get(idx).getLevel();
|
||||
|
||||
if (mid == level) {
|
||||
return idx;
|
||||
} else if (mid < level) {
|
||||
st = idx + 1;
|
||||
} else {
|
||||
en = idx - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return en;
|
||||
}
|
||||
|
||||
public MapleCharacter callPlayer(int callerCid, int callerMapid, int minLevel, int maxLevel) {
|
||||
if (emptyManager.isInEmptyInterval(minLevel, maxLevel)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<PartySearchCharacter> pscList = getStorageList();
|
||||
|
||||
int idx = bsearchStorage(pscList, maxLevel);
|
||||
for (int i = idx; i >= 0; i--) {
|
||||
PartySearchCharacter psc = pscList.get(i);
|
||||
if (!psc.isQueued()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (psc.getLevel() < minLevel) {
|
||||
break;
|
||||
}
|
||||
|
||||
MapleCharacter chr = psc.callPlayer(callerCid, callerMapid);
|
||||
if (chr != null) {
|
||||
return chr;
|
||||
}
|
||||
}
|
||||
|
||||
emptyManager.addEmptyInterval(minLevel, maxLevel);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void detachPlayer(MapleCharacter chr) {
|
||||
PartySearchCharacter toRemove = null;
|
||||
for (PartySearchCharacter psc : getStorageList()) {
|
||||
MapleCharacter player = psc.getPlayer();
|
||||
|
||||
if (player != null && player.getId() == chr.getId()) {
|
||||
toRemove = psc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (toRemove != null) {
|
||||
psWLock.lock();
|
||||
try {
|
||||
storage.remove(toRemove);
|
||||
} finally {
|
||||
psWLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
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 net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class PartySearchWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
wserv.runPartySearchUpdateSchedule();
|
||||
}
|
||||
|
||||
public PartySearchWorker(World world) {
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
@@ -342,6 +342,7 @@ public class MapleParty {
|
||||
player.getMap().addPartyMember(player);
|
||||
player.silentPartyUpdate();
|
||||
|
||||
player.updatePartySearchAvailability(false);
|
||||
player.partyOperationUpdate(party, null);
|
||||
|
||||
player.announce(MaplePacketCreator.partyCreated(party, partyplayer.getId()));
|
||||
@@ -371,6 +372,8 @@ public class MapleParty {
|
||||
player.receivePartyMemberHP();
|
||||
player.updatePartyMemberHP();
|
||||
|
||||
player.resetPartySearchInvite(party.getLeaderId());
|
||||
player.updatePartySearchAvailability(false);
|
||||
player.partyOperationUpdate(party, null);
|
||||
return true;
|
||||
} else {
|
||||
@@ -467,6 +470,7 @@ public class MapleParty {
|
||||
emc.setParty(null);
|
||||
world.updateParty(party.getId(), PartyOperation.EXPEL, expelled);
|
||||
|
||||
emc.updatePartySearchAvailability(true);
|
||||
emc.partyOperationUpdate(party, partyMembers);
|
||||
} else {
|
||||
world.updateParty(party.getId(), PartyOperation.EXPEL, expelled);
|
||||
|
||||
@@ -70,6 +70,7 @@ import net.server.worker.FishingWorker;
|
||||
import net.server.worker.HiredMerchantWorker;
|
||||
import net.server.worker.MapOwnershipWorker;
|
||||
import net.server.worker.MountTirednessWorker;
|
||||
import net.server.worker.PartySearchWorker;
|
||||
import net.server.worker.PetFullnessWorker;
|
||||
import net.server.worker.ServerMessageWorker;
|
||||
import net.server.worker.TimedMapObjectWorker;
|
||||
@@ -94,6 +95,7 @@ import net.server.coordinator.MapleInviteCoordinator;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
|
||||
import net.server.coordinator.MapleInviteCoordinator.InviteType;
|
||||
import net.server.coordinator.MapleMatchCheckerCoordinator;
|
||||
import net.server.coordinator.MaplePartySearchCoordinator;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -115,6 +117,7 @@ public class World {
|
||||
private Map<Integer, MapleGuildSummary> gsStore = new HashMap<>();
|
||||
private PlayerStorage players = new PlayerStorage();
|
||||
private MapleMatchCheckerCoordinator matchChecker = new MapleMatchCheckerCoordinator();
|
||||
private MaplePartySearchCoordinator partySearch = new MaplePartySearchCoordinator();
|
||||
|
||||
private final ReentrantReadWriteLock chnLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.WORLD_CHANNELS, true);
|
||||
private ReadLock chnRLock = chnLock.readLock();
|
||||
@@ -170,6 +173,7 @@ public class World {
|
||||
private ScheduledFuture<?> marriagesSchedule;
|
||||
private ScheduledFuture<?> mapOwnershipSchedule;
|
||||
private ScheduledFuture<?> fishingSchedule;
|
||||
private ScheduledFuture<?> partySearchSchedule;
|
||||
|
||||
public World(int world, int flag, String eventmsg, int exprate, int droprate, int bossdroprate, int mesorate, int questrate, int travelrate, int fishingrate) {
|
||||
this.id = world;
|
||||
@@ -202,6 +206,7 @@ public class World {
|
||||
marriagesSchedule = tman.register(new WeddingReservationWorker(this), ServerConstants.WEDDING_RESERVATION_INTERVAL * 60 * 1000, ServerConstants.WEDDING_RESERVATION_INTERVAL * 60 * 1000);
|
||||
mapOwnershipSchedule = tman.register(new MapOwnershipWorker(this), 20 * 1000, 20 * 1000);
|
||||
fishingSchedule = tman.register(new FishingWorker(this), 10 * 1000, 10 * 1000);
|
||||
partySearchSchedule = tman.register(new PartySearchWorker(this), 10 * 1000, 10 * 1000);
|
||||
|
||||
}
|
||||
|
||||
@@ -495,6 +500,10 @@ public class World {
|
||||
return matchChecker;
|
||||
}
|
||||
|
||||
public MaplePartySearchCoordinator getPartySearchCoordinator() {
|
||||
return partySearch;
|
||||
}
|
||||
|
||||
public void addPlayer(MapleCharacter chr) {
|
||||
players.addPlayer(chr);
|
||||
}
|
||||
@@ -1975,6 +1984,11 @@ public class World {
|
||||
}
|
||||
}
|
||||
|
||||
public void runPartySearchUpdateSchedule() {
|
||||
partySearch.updatePartySearchStorage();
|
||||
partySearch.runPartySearch();
|
||||
}
|
||||
|
||||
private void clearWorldData() {
|
||||
List<MapleParty> pList;
|
||||
partyLock.lock();
|
||||
@@ -2061,6 +2075,11 @@ public class World {
|
||||
fishingSchedule = null;
|
||||
}
|
||||
|
||||
if(partySearchSchedule != null) {
|
||||
partySearchSchedule.cancel(false);
|
||||
partySearchSchedule = null;
|
||||
}
|
||||
|
||||
players.disconnectAll();
|
||||
players = null;
|
||||
|
||||
|
||||
@@ -146,6 +146,54 @@ public class MapleStatEffect {
|
||||
private Point lt, rb;
|
||||
private byte bulletCount, bulletConsume;
|
||||
private byte mapProtection;
|
||||
private CardItemupStats cardStats;
|
||||
|
||||
private static class CardItemupStats {
|
||||
protected int itemCode, prob;
|
||||
private List<Pair<Integer, Integer>> areas;
|
||||
|
||||
private CardItemupStats(int code, int prob, List<Pair<Integer, Integer>> areas) {
|
||||
this.itemCode = code;
|
||||
this.prob = prob;
|
||||
this.areas = areas;
|
||||
}
|
||||
|
||||
private boolean isInArea(int mapid) {
|
||||
if (this.areas == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Pair<Integer, Integer> a : this.areas) {
|
||||
if (mapid >= a.left && mapid <= a.right) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActive(int mapid) {
|
||||
return cardStats == null || cardStats.isInArea(mapid);
|
||||
}
|
||||
|
||||
public int getCardRate(int mapid, int itemid) {
|
||||
if (cardStats != null) {
|
||||
if (cardStats.itemCode == Integer.MAX_VALUE) {
|
||||
return cardStats.prob;
|
||||
} else if (cardStats.itemCode < 1000) {
|
||||
if (itemid / 10000 == cardStats.itemCode) {
|
||||
return cardStats.prob;
|
||||
}
|
||||
} else {
|
||||
if (itemid == cardStats.itemCode) {
|
||||
return cardStats.prob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static MapleStatEffect loadSkillEffectFromData(MapleData source, int skillid, boolean overtime) {
|
||||
return loadFromData(source, skillid, true, overtime);
|
||||
@@ -248,7 +296,7 @@ public class MapleStatEffect {
|
||||
ret.jump = (short) MapleDataTool.getInt("jump", source, 0);
|
||||
|
||||
ret.barrier = MapleDataTool.getInt("barrier", source, 0);
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.ARIANT_PQ_SHIELD, ret.barrier);
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.AURA, ret.barrier);
|
||||
|
||||
ret.mapProtection = mapProtection(sourceid);
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_PROTECTION, Integer.valueOf(ret.mapProtection));
|
||||
@@ -303,6 +351,65 @@ public class MapleStatEffect {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP3, 1);
|
||||
break;
|
||||
}
|
||||
} else if (isMonsterCard(sourceid)) {
|
||||
int prob = 0, itemupCode = Integer.MAX_VALUE;
|
||||
List<Pair<Integer, Integer>> areas = null;
|
||||
|
||||
MapleData con = source.getChildByPath("con");
|
||||
if (con != null) {
|
||||
areas = new ArrayList<>(3);
|
||||
|
||||
for (MapleData conData : con.getChildren()) {
|
||||
int startMap = MapleDataTool.getInt("sMap", conData, 0);
|
||||
int endMap = MapleDataTool.getInt("eMap", conData, 0);
|
||||
|
||||
areas.add(new Pair<>(startMap, endMap));
|
||||
}
|
||||
}
|
||||
|
||||
if (MapleDataTool.getInt("mesoupbyitem", source, 0) != 0) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MESO_UP_BY_ITEM, 4);
|
||||
prob = MapleDataTool.getInt("prob", source, 1);
|
||||
}
|
||||
|
||||
int itemupType = MapleDataTool.getInt("itemupbyitem", source, 0);
|
||||
if (itemupType != 0) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.ITEM_UP_BY_ITEM, 4);
|
||||
prob = MapleDataTool.getInt("prob", source, 1);
|
||||
|
||||
switch (itemupType) {
|
||||
case 2:
|
||||
itemupCode = MapleDataTool.getInt("itemCode", source, 1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
itemupCode = MapleDataTool.getInt("itemRange", source, 1); // 3 digits
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (MapleDataTool.getInt("respectPimmune", source, 0) != 0) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.RESPECT_PIMMUNE, 4);
|
||||
}
|
||||
|
||||
if (MapleDataTool.getInt("respectMimmune", source, 0) != 0) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.RESPECT_MIMMUNE, 4);
|
||||
}
|
||||
|
||||
if (MapleDataTool.getString("defenseAtt", source, null) != null) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.DEFENSE_ATT, 4);
|
||||
}
|
||||
|
||||
if (MapleDataTool.getString("defenseState", source, null) != null) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.DEFENSE_STATE, 4);
|
||||
}
|
||||
|
||||
int thaw = MapleDataTool.getInt("thaw", source, 0);
|
||||
if (thaw != 0) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_PROTECTION, thaw > 0 ? 1 : 2);
|
||||
}
|
||||
|
||||
ret.cardStats = new CardItemupStats(itemupCode, prob, areas);
|
||||
} else if (isExpIncrease(sourceid)) {
|
||||
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.EXP_INCREASE, MapleDataTool.getInt("expinc", source, 0));
|
||||
}
|
||||
@@ -1208,7 +1315,7 @@ public class MapleStatEffect {
|
||||
if (localstatups.size() > 0) {
|
||||
byte[] buff = null;
|
||||
byte[] mbuff = null;
|
||||
if (getSummonMovementType() == null) {
|
||||
if (getSummonMovementType() == null && this.isActive(applyto.getMapId())) {
|
||||
buff = MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), localDuration, localstatups);
|
||||
}
|
||||
if (isDash()) {
|
||||
@@ -1253,7 +1360,7 @@ public class MapleStatEffect {
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.MORPH, Integer.valueOf(getMorph(applyto))));
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat);
|
||||
} else if (isAriantShield()) {
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.ARIANT_PQ_SHIELD, 1));
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.AURA, 1));
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat);
|
||||
}
|
||||
|
||||
@@ -1496,6 +1603,11 @@ public class MapleStatEffect {
|
||||
return sourceid == 2022269;
|
||||
}
|
||||
|
||||
public static boolean isMonsterCard(int sourceid) {
|
||||
int itemType = sourceid / 10000;
|
||||
return itemType == 238;
|
||||
}
|
||||
|
||||
private boolean isDs() {
|
||||
return skill && (sourceid == Rogue.DARK_SIGHT || sourceid == NightWalker.DARK_SIGHT);
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
return takenDamage.containsKey(chr.getId());
|
||||
}
|
||||
|
||||
private void distributeExperienceToParty(int pid, float exp, int mostDamageCid, int minThresholdLevel, int killerLevel, Set<MapleCharacter> underleveled, Map<MapleCharacter, Float> partyExpReward) {
|
||||
private void distributeExperienceToParty(int pid, float exp, int mostDamageCid, int minThresholdLevel, int killerLevel, Set<MapleCharacter> underleveled, Map<MapleCharacter, Float> partyExpReward, Set<MapleCharacter> participants) {
|
||||
MapleCharacter pchar = getMap().getAnyCharacterFromParty(pid); // thanks G h o s t, Alfred, Vcoc, BHB for poiting out a bug in detecting party members after membership transactions in a party took place
|
||||
|
||||
List<MapleCharacter> members;
|
||||
@@ -486,7 +486,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
|
||||
List<MapleCharacter> expSharers = new LinkedList<>();
|
||||
int expSharersMaxLevel = 1;
|
||||
int expParticipantsMaxLevel = 1;
|
||||
boolean hasMostDamageCid = false;
|
||||
for (MapleCharacter mc : members) {
|
||||
if (mc.getId() == mostDamageCid) {
|
||||
@@ -497,8 +497,8 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
if (Math.abs(killerLevel - mc.getLevel()) < ServerConstants.MIN_RANGELEVEL_TO_EXP_LEECH) {
|
||||
// thanks Thora for pointing out leech level limitation
|
||||
|
||||
if (expSharersMaxLevel < mc.getLevel()) {
|
||||
expSharersMaxLevel = mc.getLevel();
|
||||
if (expParticipantsMaxLevel < mc.getLevel() && participants.contains(mc)) {
|
||||
expParticipantsMaxLevel = mc.getLevel();
|
||||
}
|
||||
expSharers.add(mc);
|
||||
}
|
||||
@@ -509,14 +509,16 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
|
||||
int numExpSharers = expSharers.size();
|
||||
|
||||
// PARTY BONUS: 2p -> +2% , 3p -> +4% , 4p -> +6% , 5p -> +8% , 6p -> +10%
|
||||
// PARTY BONUS: 2p -> +5% , 3p -> +6.25% , 4p -> +7.5% , 5p -> +8.75% , 6p -> +10%
|
||||
// MOST DAMAGE BONUS: 1.5x bonus
|
||||
final float partyModifier = numExpSharers <= 1 ? 0.0f : 0.02f * (numExpSharers - 1);
|
||||
|
||||
// thanks Crypter for reporting an insufficiency on party exp bonuses
|
||||
final float partyModifier = numExpSharers <= 1 ? 0.0f : 0.05f + (0.0125f * (numExpSharers - 1));
|
||||
final float mostDamageModifier = hasMostDamageCid ? 1.5f : 1.0f;
|
||||
final float partyExp = exp * partyModifier * mostDamageModifier;
|
||||
|
||||
for (MapleCharacter mc : expSharers) {
|
||||
float levelPenaltyModifier = (float) Math.sqrt(((float) mc.getLevel()) / expSharersMaxLevel);
|
||||
float levelPenaltyModifier = (float) Math.min(1.0, Math.sqrt(((float) mc.getLevel()) / expParticipantsMaxLevel));
|
||||
partyExpReward.put(mc, partyExp * levelPenaltyModifier);
|
||||
}
|
||||
}
|
||||
@@ -640,9 +642,10 @@ public class MapleMonster extends AbstractLoadedMapleLife {
|
||||
}
|
||||
}
|
||||
|
||||
Set<MapleCharacter> participants = personalExpReward.keySet();
|
||||
int mostDamageCid = this.getHighestDamagerId();
|
||||
for (Entry<Integer, Float> party : partyExp.entrySet()) {
|
||||
distributeExperienceToParty(party.getKey(), party.getValue(), mostDamageCid, minThresholdLevel, killerLevel, underleveled, partyExpReward);
|
||||
distributeExperienceToParty(party.getKey(), party.getValue(), mostDamageCid, minThresholdLevel, killerLevel, underleveled, partyExpReward, participants);
|
||||
}
|
||||
|
||||
for(MapleCharacter mc : underleveled) {
|
||||
|
||||
@@ -239,6 +239,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
private static boolean canBuy(MapleClient c, Item newItem) {
|
||||
System.out.println(newItem.getPet().getName());
|
||||
return MapleInventoryManipulator.checkSpace(c, newItem.getItemId(), newItem.getQuantity(), newItem.getOwner()) && MapleInventoryManipulator.addFromDrop(c, newItem, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -652,7 +652,8 @@ public class MapleMap {
|
||||
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
|
||||
|
||||
for (final MonsterDropEntry de : dropEntry) {
|
||||
int dropChance = (int) Math.min((float) de.chance * chRate, Integer.MAX_VALUE);
|
||||
float cardRate = chr.getCardRate(de.itemId);
|
||||
int dropChance = (int) Math.min((float) de.chance * chRate * cardRate, Integer.MAX_VALUE);
|
||||
|
||||
if (Randomizer.nextInt(999999) < dropChance) {
|
||||
if (droptype == 3) {
|
||||
@@ -2481,7 +2482,9 @@ public class MapleMap {
|
||||
} finally {
|
||||
chrWLock.unlock();
|
||||
}
|
||||
|
||||
chr.setMapId(mapid);
|
||||
chr.updateActiveEffects();
|
||||
|
||||
if (chrSize == 1) {
|
||||
if(!hasItemMonitor()) {
|
||||
@@ -3305,11 +3308,10 @@ public class MapleMap {
|
||||
player.setPosition(newPosition);
|
||||
|
||||
try {
|
||||
Collection<MapleMapObject> visibleObjects = player.getVisibleMapObjects();
|
||||
MapleMapObject[] visibleObjectsNow = visibleObjects.toArray(new MapleMapObject[visibleObjects.size()]);
|
||||
MapleMapObject[] visibleObjects = player.getVisibleMapObjects();
|
||||
|
||||
Map<Integer, MapleMapObject> mapObjects = getCopyMapObjects();
|
||||
for (MapleMapObject mo : visibleObjectsNow) {
|
||||
for (MapleMapObject mo : visibleObjects) {
|
||||
if (mo != null) {
|
||||
if (mapObjects.get(mo.getObjectId()) == mo) {
|
||||
updateMapObjectVisibility(player, mo);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package server.partyquest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import client.MapleCharacter;
|
||||
import constants.LanguageConstants;
|
||||
@@ -10,9 +9,7 @@ import net.server.channel.Channel;
|
||||
import net.server.world.MapleParty;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import server.TimerManager;
|
||||
import server.life.MapleMonster;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapObject;
|
||||
import server.maps.MapleReactor;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
|
||||
@@ -1853,36 +1853,7 @@ public class MaplePacketCreator {
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a packet spawning a player as a mapobject to other clients.
|
||||
*
|
||||
* @param target The client receiving this packet.
|
||||
* @param chr The character to spawn to other clients.
|
||||
* @param enteringField Whether the character to spawn is not yet present in the map or already is.
|
||||
* @return The spawn player packet.
|
||||
*/
|
||||
public static byte[] spawnPlayerMapObject(MapleClient target, MapleCharacter chr, boolean enteringField) {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.SPAWN_PLAYER.getValue());
|
||||
mplew.writeInt(chr.getId());
|
||||
mplew.write(chr.getLevel()); //v83
|
||||
mplew.writeMapleAsciiString(chr.getName());
|
||||
if (chr.getGuildId() < 1) {
|
||||
mplew.writeMapleAsciiString("");
|
||||
mplew.write(new byte[6]);
|
||||
} else {
|
||||
MapleGuildSummary gs = chr.getClient().getWorldServer().getGuildSummary(chr.getGuildId(), chr.getWorld());
|
||||
if (gs != null) {
|
||||
mplew.writeMapleAsciiString(gs.getName());
|
||||
mplew.writeShort(gs.getLogoBG());
|
||||
mplew.write(gs.getLogoBGColor());
|
||||
mplew.writeShort(gs.getLogo());
|
||||
mplew.write(gs.getLogoColor());
|
||||
} else {
|
||||
mplew.writeMapleAsciiString("");
|
||||
mplew.write(new byte[6]);
|
||||
}
|
||||
}
|
||||
private static void writeForeignBuffs(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
|
||||
mplew.writeInt(0);
|
||||
mplew.writeShort(0); //v83
|
||||
mplew.write(0xFC);
|
||||
@@ -1962,6 +1933,40 @@ public class MaplePacketCreator {
|
||||
mplew.writeInt(CHAR_MAGIC_SPAWN);
|
||||
mplew.writeShort(0);
|
||||
mplew.write(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a packet spawning a player as a mapobject to other clients.
|
||||
*
|
||||
* @param target The client receiving this packet.
|
||||
* @param chr The character to spawn to other clients.
|
||||
* @param enteringField Whether the character to spawn is not yet present in the map or already is.
|
||||
* @return The spawn player packet.
|
||||
*/
|
||||
public static byte[] spawnPlayerMapObject(MapleClient target, MapleCharacter chr, boolean enteringField) {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.SPAWN_PLAYER.getValue());
|
||||
mplew.writeInt(chr.getId());
|
||||
mplew.write(chr.getLevel()); //v83
|
||||
mplew.writeMapleAsciiString(chr.getName());
|
||||
if (chr.getGuildId() < 1) {
|
||||
mplew.writeMapleAsciiString("");
|
||||
mplew.write(new byte[6]);
|
||||
} else {
|
||||
MapleGuildSummary gs = chr.getClient().getWorldServer().getGuildSummary(chr.getGuildId(), chr.getWorld());
|
||||
if (gs != null) {
|
||||
mplew.writeMapleAsciiString(gs.getName());
|
||||
mplew.writeShort(gs.getLogoBG());
|
||||
mplew.write(gs.getLogoBGColor());
|
||||
mplew.writeShort(gs.getLogo());
|
||||
mplew.write(gs.getLogoColor());
|
||||
} else {
|
||||
mplew.writeMapleAsciiString("");
|
||||
mplew.write(new byte[6]);
|
||||
}
|
||||
}
|
||||
|
||||
writeForeignBuffs(mplew, chr);
|
||||
|
||||
mplew.writeShort(chr.getJob().getId());
|
||||
|
||||
@@ -3808,6 +3813,16 @@ public class MaplePacketCreator {
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
public static byte[] partySearchInvite(MapleCharacter from) {
|
||||
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
mplew.writeShort(SendOpcode.PARTY_OPERATION.getValue());
|
||||
mplew.write(4);
|
||||
mplew.writeInt(from.getParty().getId());
|
||||
mplew.writeMapleAsciiString("PS: " + from.getName());
|
||||
mplew.write(0);
|
||||
return mplew.getPacket();
|
||||
}
|
||||
|
||||
/**
|
||||
* 10: A beginner can't create a party. 1/5/6/11/14/19: Your request for a
|
||||
* party didn't work due to an unexpected error. 12: Quit as leader of the
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="MapleSkillbookChanceFetcher" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project MapleSkillbookChanceFetcher.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="MapleSkillbookChanceFetcher-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
@@ -0,0 +1,447 @@
|
||||
# SQL File autogenerated from the MapleMesoFetcher feature by Ronan Lana.
|
||||
# Generated data takes into account mob stats such as level and boss for the meso ranges.
|
||||
# Only mobs with 4 or more items with no meso entry on the DB it was compiled are presented here.
|
||||
|
||||
INSERT IGNORE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) VALUES
|
||||
(100122, 0, 35, 52, 0, 400000),
|
||||
(100123, 0, 38, 55, 0, 400000),
|
||||
(100124, 0, 40, 59, 0, 400000),
|
||||
(100130, 0, 31, 45, 0, 400000),
|
||||
(100131, 0, 33, 49, 0, 400000),
|
||||
(100132, 0, 35, 52, 0, 400000),
|
||||
(100133, 0, 38, 55, 0, 400000),
|
||||
(100134, 0, 40, 59, 0, 400000),
|
||||
(1110130, 0, 49, 72, 0, 400000),
|
||||
(1140130, 0, 56, 83, 0, 400000),
|
||||
(2100100, 0, 58, 85, 0, 400000),
|
||||
(2100101, 0, 60, 88, 0, 400000),
|
||||
(2100106, 0, 66, 97, 0, 400000),
|
||||
(2100107, 0, 73, 108, 0, 400000),
|
||||
(2100108, 0, 78, 115, 0, 400000),
|
||||
(2110300, 0, 66, 97, 0, 400000),
|
||||
(2110301, 0, 78, 115, 0, 400000),
|
||||
(2230105, 0, 64, 94, 0, 400000),
|
||||
(2230107, 0, 66, 97, 0, 400000),
|
||||
(2230110, 0, 64, 94, 0, 400000),
|
||||
(2230111, 0, 66, 97, 0, 400000),
|
||||
(2230131, 0, 66, 97, 0, 400000),
|
||||
(3000005, 0, 81, 119, 0, 400000),
|
||||
(3100101, 0, 86, 127, 0, 400000),
|
||||
(3100102, 0, 81, 119, 0, 400000),
|
||||
(3110301, 0, 86, 127, 0, 400000),
|
||||
(3110302, 0, 95, 140, 0, 400000),
|
||||
(3110303, 0, 105, 155, 0, 400000),
|
||||
(3220000, 0, 285, 1400, 0, 400000),
|
||||
(3220001, 0, 315, 1550, 0, 400000),
|
||||
(3300000, 0, 81, 119, 0, 400000),
|
||||
(3300001, 0, 81, 119, 0, 400000),
|
||||
(3300002, 0, 83, 123, 0, 400000),
|
||||
(3300003, 0, 86, 127, 0, 400000),
|
||||
(3300004, 0, 89, 131, 0, 400000),
|
||||
(3300005, 0, 95, 140, 0, 400000),
|
||||
(3300006, 0, 95, 140, 0, 400000),
|
||||
(3300007, 0, 95, 140, 0, 400000),
|
||||
(3300008, 0, 315, 1550, 0, 400000),
|
||||
(4110300, 0, 120, 177, 0, 400000),
|
||||
(4110301, 0, 132, 195, 0, 400000),
|
||||
(4130103, 0, 423, 2080, 0, 400000),
|
||||
(4220000, 0, 396, 1950, 0, 400000),
|
||||
(4230122, 0, 120, 177, 0, 400000),
|
||||
(4230125, 0, 128, 189, 0, 400000),
|
||||
(4230400, 0, 132, 195, 0, 400000),
|
||||
(4230502, 0, 124, 182, 0, 400000),
|
||||
(4230503, 0, 132, 195, 0, 400000),
|
||||
(4230504, 0, 132, 195, 0, 400000),
|
||||
(4230600, 0, 112, 165, 0, 400000),
|
||||
(4240000, 0, 151, 222, 0, 400000),
|
||||
(4250000, 0, 120, 177, 0, 400000),
|
||||
(4250001, 0, 137, 201, 0, 400000),
|
||||
(5110300, 0, 156, 230, 0, 400000),
|
||||
(5120500, 0, 190, 280, 0, 400000),
|
||||
(5120501, 0, 172, 254, 0, 400000),
|
||||
(5120502, 0, 178, 262, 0, 400000),
|
||||
(5120505, 0, 203, 299, 0, 400000),
|
||||
(5120506, 0, 184, 271, 0, 400000),
|
||||
(5130105, 0, 190, 280, 0, 400000),
|
||||
(5130108, 0, 196, 289, 0, 400000),
|
||||
(5220000, 0, 552, 2710, 0, 400000),
|
||||
(5220002, 0, 468, 2300, 0, 400000),
|
||||
(5220003, 0, 630, 3090, 0, 400000),
|
||||
(5220004, 0, 468, 2300, 0, 400000),
|
||||
(5250000, 0, 184, 271, 0, 400000),
|
||||
(5250001, 0, 161, 237, 0, 400000),
|
||||
(5250002, 0, 196, 289, 0, 400000),
|
||||
(6110300, 0, 255, 377, 0, 400000),
|
||||
(6130102, 0, 217, 320, 0, 400000),
|
||||
(6130103, 0, 217, 320, 0, 400000),
|
||||
(6130203, 0, 217, 320, 0, 400000),
|
||||
(6130207, 0, 231, 341, 0, 400000),
|
||||
(6130209, 0, 264, 389, 0, 400000),
|
||||
(6220000, 0, 765, 3770, 0, 400000),
|
||||
(6220001, 0, 765, 3770, 0, 400000),
|
||||
(6230100, 0, 231, 341, 0, 400000),
|
||||
(6230401, 0, 239, 353, 0, 400000),
|
||||
(6300005, 0, 765, 3770, 0, 400000),
|
||||
(6400006, 0, 384, 1890, 0, 400000),
|
||||
(6400008, 0, 552, 2710, 0, 400000),
|
||||
(6400009, 0, 552, 2710, 0, 400000),
|
||||
(7110300, 0, 355, 524, 0, 400000),
|
||||
(7110301, 0, 332, 490, 0, 400000),
|
||||
(7120103, 0, 301, 444, 0, 400000),
|
||||
(7120104, 0, 311, 459, 0, 400000),
|
||||
(7120106, 0, 355, 524, 0, 400000),
|
||||
(7120107, 0, 355, 524, 0, 400000),
|
||||
(7120108, 0, 379, 559, 0, 400000),
|
||||
(7120109, 0, 405, 597, 0, 400000),
|
||||
(7130000, 0, 332, 490, 0, 400000),
|
||||
(7130002, 0, 321, 474, 0, 400000),
|
||||
(7130003, 0, 367, 541, 0, 400000),
|
||||
(7130004, 0, 391, 578, 0, 400000),
|
||||
(7130102, 0, 391, 578, 0, 400000),
|
||||
(7130103, 0, 332, 490, 0, 400000),
|
||||
(7130400, 0, 903, 4440, 0, 400000),
|
||||
(7130401, 0, 903, 4440, 0, 400000),
|
||||
(7130402, 0, 903, 4440, 0, 400000),
|
||||
(7130601, 0, 367, 541, 0, 400000),
|
||||
(7220000, 0, 933, 4590, 0, 400000),
|
||||
(7220001, 0, 903, 4440, 0, 400000),
|
||||
(7220002, 0, 1137, 5590, 0, 400000),
|
||||
(8110300, 0, 418, 617, 0, 400000),
|
||||
(8120102, 0, 446, 659, 0, 400000),
|
||||
(8120103, 0, 477, 704, 0, 400000),
|
||||
(8120104, 0, 509, 752, 0, 400000),
|
||||
(8120105, 0, 544, 803, 0, 400000),
|
||||
(8120106, 0, 562, 830, 0, 400000),
|
||||
(8120107, 0, 562, 830, 0, 400000),
|
||||
(8140000, 0, 418, 617, 0, 400000),
|
||||
(8140100, 0, 446, 659, 0, 400000),
|
||||
(8140511, 0, 581, 871, 0, 400000),
|
||||
(8140512, 0, 608, 908, 0, 400000),
|
||||
(8140600, 0, 594, 889, 0, 400000),
|
||||
(8140702, 0, 637, 946, 0, 400000),
|
||||
(8140703, 0, 666, 986, 0, 400000),
|
||||
(8141300, 0, 622, 927, 0, 400000),
|
||||
(8150000, 0, 2142, 10490, 0, 400000),
|
||||
(8150100, 0, 714, 1049, 0, 400000),
|
||||
(8150101, 0, 747, 1093, 0, 400000),
|
||||
(8150200, 0, 714, 1049, 0, 400000),
|
||||
(8150201, 0, 800, 1162, 0, 400000),
|
||||
(8150300, 0, 666, 986, 0, 400000),
|
||||
(8150301, 0, 730, 1070, 0, 400000),
|
||||
(8150302, 0, 764, 1115, 0, 400000),
|
||||
(8190001, 0, 800, 1162, 0, 400000),
|
||||
(8220003, 0, 3381, 15830, 0, 400000),
|
||||
(8220005, 0, 4350, 19860, 0, 400000),
|
||||
(8220006, 0, 5466, 24400, 0, 400000),
|
||||
(8220007, 0, 1704, 8530, 0, 400000),
|
||||
(8220009, 0, 1479, 7280, 0, 400000),
|
||||
(8830000, 0, 2400, 11620, 0, 400000),
|
||||
(9001009, 0, 1254, 6170, 0, 400000),
|
||||
(9001011, 0, 95, 140, 0, 400000),
|
||||
(9200016, 0, 81, 119, 0, 400000),
|
||||
(9200019, 0, 203, 299, 0, 400000),
|
||||
(9300011, 0, 109, 160, 0, 400000),
|
||||
(9300058, 0, 38, 55, 0, 400000),
|
||||
(9300059, 0, 42, 61, 0, 400000),
|
||||
(9300060, 0, 120, 177, 0, 400000),
|
||||
(9300078, 0, 800, 1162, 0, 400000),
|
||||
(9300080, 0, 282, 416, 0, 400000),
|
||||
(9300096, 0, 544, 803, 0, 400000),
|
||||
(9300105, 0, 717, 3530, 0, 400000),
|
||||
(9300106, 0, 846, 4160, 0, 400000),
|
||||
(9300127, 0, 81, 119, 0, 400000),
|
||||
(9300129, 0, 81, 119, 0, 400000),
|
||||
(9300131, 0, 109, 160, 0, 400000),
|
||||
(9300132, 0, 81, 119, 0, 400000),
|
||||
(9300133, 0, 81, 119, 0, 400000),
|
||||
(9300134, 0, 81, 119, 0, 400000),
|
||||
(9300136, 0, 243, 1190, 0, 400000),
|
||||
(9300139, 0, 1296, 6380, 0, 400000),
|
||||
(9300155, 0, 38, 55, 0, 400000),
|
||||
(9300160, 0, 396, 1950, 0, 400000),
|
||||
(9300161, 0, 396, 1950, 0, 400000),
|
||||
(9300163, 0, 1127, 1583, 0, 400000),
|
||||
(9300164, 0, 1127, 1583, 0, 400000),
|
||||
(9300165, 0, 1127, 1583, 0, 400000),
|
||||
(9300182, 0, 1479, 7280, 0, 400000),
|
||||
(9300184, 0, 174, 850, 0, 400000),
|
||||
(9300185, 0, 285, 1400, 0, 400000),
|
||||
(9300186, 0, 315, 1550, 0, 400000),
|
||||
(9300187, 0, 336, 1650, 0, 400000),
|
||||
(9300188, 0, 468, 2300, 0, 400000),
|
||||
(9300189, 0, 468, 2300, 0, 400000),
|
||||
(9300190, 0, 552, 2710, 0, 400000),
|
||||
(9300191, 0, 651, 3200, 0, 400000),
|
||||
(9300192, 0, 570, 2800, 0, 400000),
|
||||
(9300193, 0, 630, 3090, 0, 400000),
|
||||
(9300194, 0, 765, 3770, 0, 400000),
|
||||
(9300195, 0, 765, 3770, 0, 400000),
|
||||
(9300196, 0, 765, 3770, 0, 400000),
|
||||
(9300197, 0, 765, 3770, 0, 400000),
|
||||
(9300198, 0, 651, 3200, 0, 400000),
|
||||
(9300199, 0, 903, 4440, 0, 400000),
|
||||
(9300200, 0, 933, 4590, 0, 400000),
|
||||
(9300201, 0, 1479, 7280, 0, 400000),
|
||||
(9300202, 0, 1137, 5590, 0, 400000),
|
||||
(9300203, 0, 1254, 6170, 0, 400000),
|
||||
(9300204, 0, 1383, 6810, 0, 400000),
|
||||
(9300205, 0, 1296, 6380, 0, 400000),
|
||||
(9300206, 0, 1479, 7280, 0, 400000),
|
||||
(9300207, 0, 1479, 7280, 0, 400000),
|
||||
(9300208, 0, 1704, 8530, 0, 400000),
|
||||
(9300209, 0, 1704, 8530, 0, 400000),
|
||||
(9300210, 0, 2142, 10490, 0, 400000),
|
||||
(9300211, 0, 2400, 11620, 0, 400000),
|
||||
(9300212, 0, 2400, 11620, 0, 400000),
|
||||
(9300213, 0, 3381, 15830, 0, 400000),
|
||||
(9300214, 0, 3792, 17550, 0, 400000),
|
||||
(9300215, 0, 6714, 29370, 0, 400000),
|
||||
(9300217, 0, 32, 47, 0, 400000),
|
||||
(9300218, 0, 34, 50, 0, 400000),
|
||||
(9300219, 0, 34, 50, 0, 400000),
|
||||
(9300220, 0, 52, 77, 0, 400000),
|
||||
(9300221, 0, 68, 101, 0, 400000),
|
||||
(9300222, 0, 75, 111, 0, 400000),
|
||||
(9300223, 0, 36, 54, 0, 400000),
|
||||
(9300224, 0, 102, 150, 0, 400000),
|
||||
(9300225, 0, 102, 150, 0, 400000),
|
||||
(9300226, 0, 112, 165, 0, 400000),
|
||||
(9300227, 0, 102, 150, 0, 400000),
|
||||
(9300228, 0, 146, 215, 0, 400000),
|
||||
(9300229, 0, 39, 57, 0, 400000),
|
||||
(9300230, 0, 116, 171, 0, 400000),
|
||||
(9300231, 0, 137, 201, 0, 400000),
|
||||
(9300232, 0, 92, 136, 0, 400000),
|
||||
(9300233, 0, 112, 165, 0, 400000),
|
||||
(9300234, 0, 86, 127, 0, 400000),
|
||||
(9300235, 0, 167, 245, 0, 400000),
|
||||
(9300236, 0, 190, 280, 0, 400000),
|
||||
(9300237, 0, 210, 309, 0, 400000),
|
||||
(9300238, 0, 66, 97, 0, 400000),
|
||||
(9300239, 0, 120, 177, 0, 400000),
|
||||
(9300240, 0, 132, 195, 0, 400000),
|
||||
(9300241, 0, 282, 416, 0, 400000),
|
||||
(9300242, 0, 301, 444, 0, 400000),
|
||||
(9300243, 0, 190, 280, 0, 400000),
|
||||
(9300244, 0, 190, 280, 0, 400000),
|
||||
(9300245, 0, 217, 320, 0, 400000),
|
||||
(9300246, 0, 231, 341, 0, 400000),
|
||||
(9300247, 0, 255, 377, 0, 400000),
|
||||
(9300248, 0, 264, 389, 0, 400000),
|
||||
(9300249, 0, 301, 444, 0, 400000),
|
||||
(9300250, 0, 355, 524, 0, 400000),
|
||||
(9300251, 0, 332, 490, 0, 400000),
|
||||
(9300252, 0, 132, 195, 0, 400000),
|
||||
(9300253, 0, 156, 230, 0, 400000),
|
||||
(9300254, 0, 332, 490, 0, 400000),
|
||||
(9300255, 0, 141, 208, 0, 400000),
|
||||
(9300256, 0, 217, 320, 0, 400000),
|
||||
(9300257, 0, 217, 320, 0, 400000),
|
||||
(9300258, 0, 255, 377, 0, 400000),
|
||||
(9300259, 0, 58, 85, 0, 400000),
|
||||
(9300260, 0, 418, 617, 0, 400000),
|
||||
(9300261, 0, 544, 803, 0, 400000),
|
||||
(9300262, 0, 544, 803, 0, 400000),
|
||||
(9300263, 0, 544, 803, 0, 400000),
|
||||
(9300264, 0, 764, 1115, 0, 400000),
|
||||
(9300265, 0, 730, 1070, 0, 400000),
|
||||
(9300266, 0, 933, 4590, 0, 400000),
|
||||
(9300267, 0, 1254, 6170, 0, 400000),
|
||||
(9300268, 0, 933, 4590, 0, 400000),
|
||||
(9300269, 0, 174, 850, 0, 400000),
|
||||
(9300270, 0, 418, 617, 0, 400000),
|
||||
(9300274, 0, 39, 57, 0, 400000),
|
||||
(9300289, 0, 1704, 8530, 0, 400000),
|
||||
(9300294, 0, 2142, 10490, 0, 400000),
|
||||
(9300315, 0, 483, 2370, 0, 400000),
|
||||
(9300316, 0, 516, 2540, 0, 400000),
|
||||
(9300317, 0, 552, 2710, 0, 400000),
|
||||
(9300318, 0, 588, 2890, 0, 400000),
|
||||
(9300319, 0, 630, 3090, 0, 400000),
|
||||
(9300320, 0, 672, 3300, 0, 400000),
|
||||
(9300321, 0, 717, 3530, 0, 400000),
|
||||
(9300322, 0, 765, 3770, 0, 400000),
|
||||
(9300332, 0, 112, 165, 0, 400000),
|
||||
(9300334, 0, 151, 222, 0, 400000),
|
||||
(9300335, 0, 116, 171, 0, 400000),
|
||||
(9300336, 0, 137, 201, 0, 400000),
|
||||
(9300337, 0, 137, 201, 0, 400000),
|
||||
(9300367, 0, 126, 610, 0, 400000),
|
||||
(9300368, 0, 174, 850, 0, 400000),
|
||||
(9300369, 0, 243, 1190, 0, 400000),
|
||||
(9300370, 0, 336, 1650, 0, 400000),
|
||||
(9300371, 0, 468, 2300, 0, 400000),
|
||||
(9300372, 0, 651, 3200, 0, 400000),
|
||||
(9300373, 0, 903, 4440, 0, 400000),
|
||||
(9300374, 0, 1254, 6170, 0, 400000),
|
||||
(9300375, 0, 1704, 8530, 0, 400000),
|
||||
(9300376, 0, 1704, 8530, 0, 400000),
|
||||
(9300377, 0, 2691, 12890, 0, 400000),
|
||||
(9303000, 0, 42, 61, 0, 400000),
|
||||
(9303001, 0, 42, 61, 0, 400000),
|
||||
(9303003, 0, 42, 61, 0, 400000),
|
||||
(9303004, 0, 42, 61, 0, 400000),
|
||||
(9303005, 0, 71, 104, 0, 400000),
|
||||
(9303006, 0, 71, 104, 0, 400000),
|
||||
(9303007, 0, 71, 104, 0, 400000),
|
||||
(9303008, 0, 71, 104, 0, 400000),
|
||||
(9303009, 0, 161, 237, 0, 400000),
|
||||
(9303010, 0, 161, 237, 0, 400000),
|
||||
(9303011, 0, 161, 237, 0, 400000),
|
||||
(9303013, 0, 432, 638, 0, 400000),
|
||||
(9303014, 0, 432, 638, 0, 400000),
|
||||
(9303016, 0, 432, 638, 0, 400000),
|
||||
(9400009, 0, 7014, 8225, 0, 400000),
|
||||
(9400012, 0, 217, 320, 0, 400000),
|
||||
(9400120, 0, 1911, 9460, 0, 400000),
|
||||
(9400122, 0, 1911, 9460, 0, 400000),
|
||||
(9400200, 0, 184, 271, 0, 400000),
|
||||
(9400203, 0, 112, 165, 0, 400000),
|
||||
(9400205, 0, 1704, 8530, 0, 400000),
|
||||
(9400238, 0, 81, 119, 0, 400000),
|
||||
(9400239, 0, 66, 97, 0, 400000),
|
||||
(9400241, 0, 38, 55, 0, 400000),
|
||||
(9400242, 0, 42, 61, 0, 400000),
|
||||
(9400243, 0, 184, 271, 0, 400000),
|
||||
(9400244, 0, 210, 309, 0, 400000),
|
||||
(9400245, 0, 66, 97, 0, 400000),
|
||||
(9400246, 0, 62, 91, 0, 400000),
|
||||
(9400247, 0, 81, 119, 0, 400000),
|
||||
(9400248, 0, 66, 97, 0, 400000),
|
||||
(9400500, 0, 93, 450, 0, 400000),
|
||||
(9400501, 0, 35, 52, 0, 400000),
|
||||
(9400502, 0, 105, 520, 0, 400000),
|
||||
(9400503, 0, 105, 520, 0, 400000),
|
||||
(9400504, 0, 31, 45, 0, 400000),
|
||||
(9400538, 0, 56, 83, 0, 400000),
|
||||
(9400539, 0, 60, 88, 0, 400000),
|
||||
(9400540, 0, 68, 101, 0, 400000),
|
||||
(9400541, 0, 68, 101, 0, 400000),
|
||||
(9400542, 0, 98, 145, 0, 400000),
|
||||
(9400543, 0, 116, 171, 0, 400000),
|
||||
(9400544, 0, 156, 230, 0, 400000),
|
||||
(9400546, 0, 128, 189, 0, 400000),
|
||||
(9400547, 0, 73, 108, 0, 400000),
|
||||
(9400548, 0, 81, 119, 0, 400000),
|
||||
(9400550, 0, 73, 108, 0, 400000),
|
||||
(9400556, 0, 60, 88, 0, 400000),
|
||||
(9400558, 0, 81, 119, 0, 400000),
|
||||
(9400560, 0, 156, 230, 0, 400000),
|
||||
(9400561, 0, 217, 320, 0, 400000),
|
||||
(9400562, 0, 217, 320, 0, 400000),
|
||||
(9400563, 0, 112, 165, 0, 400000),
|
||||
(9400565, 0, 60, 88, 0, 400000),
|
||||
(9400570, 0, 49, 72, 0, 400000),
|
||||
(9400571, 0, 468, 2300, 0, 400000),
|
||||
(9400573, 0, 112, 165, 0, 400000),
|
||||
(9400574, 0, 714, 1049, 0, 400000),
|
||||
(9400576, 0, 301, 444, 0, 400000),
|
||||
(9400578, 0, 568, 853, 0, 400000),
|
||||
(9400579, 0, 714, 1049, 0, 400000),
|
||||
(9400580, 0, 637, 946, 0, 400000),
|
||||
(9400581, 0, 418, 617, 0, 400000),
|
||||
(9400582, 0, 1127, 1583, 0, 400000),
|
||||
(9400609, 0, 204, 1010, 0, 400000),
|
||||
(9400612, 0, 204, 1010, 0, 400000),
|
||||
(9400633, 0, 258, 1270, 0, 400000),
|
||||
(9400644, 0, 42, 61, 0, 400000),
|
||||
(9410014, 0, 493, 728, 0, 400000),
|
||||
(9410015, 0, 1479, 7280, 0, 400000),
|
||||
(9420507, 0, 146, 215, 0, 400000),
|
||||
(9420527, 0, 132, 195, 0, 400000),
|
||||
(9420528, 0, 141, 208, 0, 400000),
|
||||
(9420529, 0, 167, 245, 0, 400000),
|
||||
(9420530, 0, 190, 280, 0, 400000),
|
||||
(9420531, 0, 210, 309, 0, 400000),
|
||||
(9420532, 0, 210, 309, 0, 400000),
|
||||
(9420533, 0, 224, 330, 0, 400000),
|
||||
(9420534, 0, 255, 377, 0, 400000),
|
||||
(9420535, 0, 282, 416, 0, 400000),
|
||||
(9420536, 0, 321, 474, 0, 400000),
|
||||
(9420537, 0, 355, 524, 0, 400000),
|
||||
(9420538, 0, 446, 659, 0, 400000),
|
||||
(9420539, 0, 526, 777, 0, 400000),
|
||||
(9420545, 0, 210, 309, 0, 400000),
|
||||
(9420550, 0, 210, 309, 0, 400000),
|
||||
(9500101, 0, 38, 55, 0, 400000),
|
||||
(9500102, 0, 39, 57, 0, 400000),
|
||||
(9500103, 0, 49, 72, 0, 400000),
|
||||
(9500104, 0, 44, 65, 0, 400000),
|
||||
(9500105, 0, 49, 72, 0, 400000),
|
||||
(9500106, 0, 62, 91, 0, 400000),
|
||||
(9500107, 0, 81, 119, 0, 400000),
|
||||
(9500108, 0, 86, 127, 0, 400000),
|
||||
(9500109, 0, 86, 127, 0, 400000),
|
||||
(9500110, 0, 95, 140, 0, 400000),
|
||||
(9500111, 0, 95, 140, 0, 400000),
|
||||
(9500112, 0, 95, 140, 0, 400000),
|
||||
(9500113, 0, 98, 145, 0, 400000),
|
||||
(9500115, 0, 102, 150, 0, 400000),
|
||||
(9500116, 0, 112, 165, 0, 400000),
|
||||
(9500117, 0, 98, 145, 0, 400000),
|
||||
(9500118, 0, 109, 160, 0, 400000),
|
||||
(9500119, 0, 109, 160, 0, 400000),
|
||||
(9500120, 0, 132, 195, 0, 400000),
|
||||
(9500121, 0, 146, 215, 0, 400000),
|
||||
(9500122, 0, 151, 222, 0, 400000),
|
||||
(9500123, 0, 210, 309, 0, 400000),
|
||||
(9500124, 0, 651, 3200, 0, 400000),
|
||||
(9500125, 0, 217, 320, 0, 400000),
|
||||
(9500126, 0, 247, 365, 0, 400000),
|
||||
(9500127, 0, 273, 402, 0, 400000),
|
||||
(9500128, 0, 282, 416, 0, 400000),
|
||||
(9500129, 0, 301, 444, 0, 400000),
|
||||
(9500130, 0, 903, 4440, 0, 400000),
|
||||
(9500131, 0, 332, 490, 0, 400000),
|
||||
(9500132, 0, 355, 524, 0, 400000),
|
||||
(9500134, 0, 418, 617, 0, 400000),
|
||||
(9500135, 0, 493, 728, 0, 400000),
|
||||
(9500136, 0, 682, 1006, 0, 400000),
|
||||
(9500137, 0, 637, 946, 0, 400000),
|
||||
(9500138, 0, 568, 853, 0, 400000),
|
||||
(9500139, 0, 1254, 6170, 0, 400000),
|
||||
(9500140, 0, 2142, 10490, 0, 400000),
|
||||
(9500156, 0, 146, 215, 0, 400000),
|
||||
(9500157, 0, 95, 140, 0, 400000),
|
||||
(9500158, 0, 903, 4440, 0, 400000),
|
||||
(9500159, 0, 903, 4440, 0, 400000),
|
||||
(9500160, 0, 903, 4440, 0, 400000),
|
||||
(9500161, 0, 418, 617, 0, 400000),
|
||||
(9500162, 0, 418, 617, 0, 400000),
|
||||
(9500163, 0, 461, 681, 0, 400000),
|
||||
(9500164, 0, 544, 803, 0, 400000),
|
||||
(9500165, 0, 544, 803, 0, 400000),
|
||||
(9500166, 0, 544, 803, 0, 400000),
|
||||
(9500178, 0, 112, 165, 0, 400000),
|
||||
(9500180, 0, 1704, 8530, 0, 400000),
|
||||
(9500181, 0, 1704, 8530, 0, 400000),
|
||||
(9500306, 0, 174, 850, 0, 400000),
|
||||
(9500307, 0, 285, 1400, 0, 400000),
|
||||
(9500308, 0, 468, 2300, 0, 400000),
|
||||
(9500309, 0, 552, 2710, 0, 400000),
|
||||
(9500310, 0, 630, 3090, 0, 400000),
|
||||
(9500311, 0, 765, 3770, 0, 400000),
|
||||
(9500312, 0, 903, 4440, 0, 400000),
|
||||
(9500313, 0, 933, 4590, 0, 400000),
|
||||
(9500314, 0, 1137, 5590, 0, 400000),
|
||||
(9500317, 0, 126, 610, 0, 400000),
|
||||
(9500318, 0, 336, 1650, 0, 400000),
|
||||
(9500319, 0, 903, 4440, 0, 400000),
|
||||
(9500321, 0, 42, 61, 0, 400000),
|
||||
(9500326, 0, 396, 1950, 0, 400000),
|
||||
(9500327, 0, 243, 1190, 0, 400000),
|
||||
(9500328, 0, 285, 1400, 0, 400000),
|
||||
(9500331, 0, 552, 2710, 0, 400000),
|
||||
(9500332, 0, 396, 1950, 0, 400000),
|
||||
(9500333, 0, 468, 2300, 0, 400000),
|
||||
(9500334, 0, 552, 2710, 0, 400000),
|
||||
(9500335, 0, 468, 2300, 0, 400000),
|
||||
(9500366, 0, 49, 72, 0, 400000),
|
||||
(9500367, 0, 49, 72, 0, 400000),
|
||||
(9500368, 0, 49, 72, 0, 400000),
|
||||
(9500369, 0, 49, 72, 0, 400000),
|
||||
(9500370, 0, 49, 72, 0, 400000),
|
||||
(9500371, 0, 49, 72, 0, 400000),
|
||||
(9500372, 0, 49, 72, 0, 400000);
|
||||
|
||||
DELETE FROM drop_data WHERE dropperid >= 9300184 AND dropperid <= 9300215 AND itemid = 0;
|
||||
Binary file not shown.
@@ -0,0 +1,619 @@
|
||||
# SQL File autogenerated from the MapleSkillbookChanceFetcher feature by Ronan Lana.
|
||||
# Generated data takes into account mob stats such as level and boss for the chance rates.
|
||||
|
||||
REPLACE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) VALUES
|
||||
(851000, 2290132, 1, 1, 0, 3861),
|
||||
(7090000, 2290087, 1, 1, 0, 40000),
|
||||
(8090000, 2290045, 1, 1, 0, 40000),
|
||||
(8140103, 2290044, 1, 1, 0, 2000),
|
||||
(8140511, 2290009, 1, 1, 0, 2000),
|
||||
(8140511, 2290050, 1, 1, 0, 2000),
|
||||
(8140511, 2290083, 1, 1, 0, 2000),
|
||||
(8140511, 2290134, 1, 1, 0, 6000),
|
||||
(8140512, 2290013, 1, 1, 0, 2000),
|
||||
(8140512, 2290067, 1, 1, 0, 2000),
|
||||
(8140512, 2290082, 1, 1, 0, 2000),
|
||||
(8140512, 2290097, 1, 1, 0, 2000),
|
||||
(8140512, 2290116, 1, 1, 0, 2000),
|
||||
(8140512, 2290131, 1, 1, 0, 6000),
|
||||
(8140600, 2290132, 1, 1, 0, 6000),
|
||||
(8140700, 2290106, 1, 1, 0, 2000),
|
||||
(8140700, 2290126, 1, 1, 0, 6000),
|
||||
(8140701, 2290122, 1, 1, 0, 2000),
|
||||
(8140702, 2290112, 1, 1, 0, 2000),
|
||||
(8140703, 2290088, 1, 1, 0, 2000),
|
||||
(8140703, 2290099, 1, 1, 0, 2000),
|
||||
(8141000, 2290082, 1, 1, 0, 2000),
|
||||
(8141000, 2290097, 1, 1, 0, 2000),
|
||||
(8141100, 2280005, 1, 1, 0, 2000),
|
||||
(8141300, 2290098, 1, 1, 0, 2000),
|
||||
(8142100, 2290032, 1, 1, 0, 2000),
|
||||
(8142100, 2290082, 1, 1, 0, 2000),
|
||||
(8142100, 2290114, 1, 1, 0, 2000),
|
||||
(8143000, 2280004, 1, 1, 0, 2000),
|
||||
(8150000, 2280013, 1, 1, 0, 120000),
|
||||
(8150000, 2290070, 1, 1, 0, 40000),
|
||||
(8150000, 2290091, 1, 1, 0, 40000),
|
||||
(8150100, 2290042, 1, 1, 0, 2000),
|
||||
(8150100, 2290053, 1, 1, 0, 2000),
|
||||
(8150100, 2290073, 1, 1, 0, 2000),
|
||||
(8150100, 2290102, 1, 1, 0, 2000),
|
||||
(8150100, 2290118, 1, 1, 0, 2000),
|
||||
(8150101, 2290017, 1, 1, 0, 2000),
|
||||
(8150101, 2290021, 1, 1, 0, 2000),
|
||||
(8150101, 2290035, 1, 1, 0, 2000),
|
||||
(8150101, 2290042, 1, 1, 0, 2000),
|
||||
(8150101, 2290052, 1, 1, 0, 2000),
|
||||
(8150101, 2290102, 1, 1, 0, 2000),
|
||||
(8150200, 2290024, 1, 1, 0, 2000),
|
||||
(8150200, 2290100, 1, 1, 0, 2000),
|
||||
(8150200, 2290135, 1, 1, 0, 6000),
|
||||
(8150201, 2290004, 1, 1, 0, 2000),
|
||||
(8150201, 2290006, 1, 1, 0, 2000),
|
||||
(8150201, 2290024, 1, 1, 0, 2000),
|
||||
(8150201, 2290036, 1, 1, 0, 2000),
|
||||
(8150201, 2290056, 1, 1, 0, 2000),
|
||||
(8150201, 2290072, 1, 1, 0, 2000),
|
||||
(8150201, 2290078, 1, 1, 0, 2000),
|
||||
(8150201, 2290117, 1, 1, 0, 2000),
|
||||
(8150300, 2290003, 1, 1, 0, 2000),
|
||||
(8150300, 2290033, 1, 1, 0, 2000),
|
||||
(8150300, 2290111, 1, 1, 0, 2000),
|
||||
(8150300, 2290120, 1, 1, 0, 2000),
|
||||
(8150300, 2290127, 1, 1, 0, 6000),
|
||||
(8150301, 2290023, 1, 1, 0, 2000),
|
||||
(8150301, 2290029, 1, 1, 0, 2000),
|
||||
(8150301, 2290101, 1, 1, 0, 2000),
|
||||
(8150301, 2290107, 1, 1, 0, 2000),
|
||||
(8150302, 2290010, 1, 1, 0, 2000),
|
||||
(8150302, 2290019, 1, 1, 0, 2000),
|
||||
(8150302, 2290026, 1, 1, 0, 2000),
|
||||
(8150302, 2290076, 1, 1, 0, 2000),
|
||||
(8150302, 2290085, 1, 1, 0, 2000),
|
||||
(8150302, 2290096, 1, 1, 0, 2000),
|
||||
(8150302, 2290113, 1, 1, 0, 2000),
|
||||
(8150302, 2290119, 1, 1, 0, 2000),
|
||||
(8150302, 2290128, 1, 1, 0, 6000),
|
||||
(8160000, 2290017, 1, 1, 0, 2000),
|
||||
(8160000, 2290045, 1, 1, 0, 2000),
|
||||
(8160000, 2290065, 1, 1, 0, 2000),
|
||||
(8160000, 2290067, 1, 1, 0, 2000),
|
||||
(8160000, 2290081, 1, 1, 0, 2000),
|
||||
(8170000, 2290012, 1, 1, 0, 2000),
|
||||
(8170000, 2290086, 1, 1, 0, 2000),
|
||||
(8170000, 2290087, 1, 1, 0, 2000),
|
||||
(8170000, 2290134, 1, 1, 0, 6000),
|
||||
(8180000, 2290002, 1, 1, 0, 40000),
|
||||
(8180000, 2290003, 1, 1, 0, 40000),
|
||||
(8180000, 2290014, 1, 1, 0, 40000),
|
||||
(8180000, 2290015, 1, 1, 0, 40000),
|
||||
(8180000, 2290030, 1, 1, 0, 40000),
|
||||
(8180000, 2290035, 1, 1, 0, 40000),
|
||||
(8180000, 2290036, 1, 1, 0, 40000),
|
||||
(8180000, 2290063, 1, 1, 0, 40000),
|
||||
(8180000, 2290080, 1, 1, 0, 40000),
|
||||
(8180000, 2290098, 1, 1, 0, 40000),
|
||||
(8180000, 2290101, 1, 1, 0, 40000),
|
||||
(8180000, 2290117, 1, 1, 0, 40000),
|
||||
(8180000, 2290130, 1, 1, 0, 120000),
|
||||
(8180001, 2290018, 1, 1, 0, 40000),
|
||||
(8180001, 2290019, 1, 1, 0, 40000),
|
||||
(8180001, 2290032, 1, 1, 0, 40000),
|
||||
(8180001, 2290042, 1, 1, 0, 40000),
|
||||
(8180001, 2290058, 1, 1, 0, 40000),
|
||||
(8180001, 2290059, 1, 1, 0, 40000),
|
||||
(8180001, 2290068, 1, 1, 0, 40000),
|
||||
(8180001, 2290069, 1, 1, 0, 40000),
|
||||
(8180001, 2290072, 1, 1, 0, 40000),
|
||||
(8180001, 2290092, 1, 1, 0, 40000),
|
||||
(8180001, 2290099, 1, 1, 0, 40000),
|
||||
(8180001, 2290100, 1, 1, 0, 40000),
|
||||
(8180001, 2290102, 1, 1, 0, 40000),
|
||||
(8180001, 2290119, 1, 1, 0, 40000),
|
||||
(8180001, 2290128, 1, 1, 0, 120000),
|
||||
(8190000, 2280016, 1, 1, 0, 6000),
|
||||
(8190000, 2290030, 1, 1, 0, 2000),
|
||||
(8190000, 2290044, 1, 1, 0, 2000),
|
||||
(8190000, 2290054, 1, 1, 0, 2000),
|
||||
(8190000, 2290066, 1, 1, 0, 2000),
|
||||
(8190000, 2290075, 1, 1, 0, 2000),
|
||||
(8190000, 2290092, 1, 1, 0, 2000),
|
||||
(8190000, 2290103, 1, 1, 0, 2000),
|
||||
(8190002, 2290000, 1, 1, 0, 2000),
|
||||
(8190002, 2290008, 1, 1, 0, 2000),
|
||||
(8190002, 2290018, 1, 1, 0, 2000),
|
||||
(8190002, 2290038, 1, 1, 0, 2000),
|
||||
(8190002, 2290060, 1, 1, 0, 2000),
|
||||
(8190002, 2290080, 1, 1, 0, 2000),
|
||||
(8190002, 2290124, 1, 1, 0, 2000),
|
||||
(8190003, 2280013, 1, 1, 0, 6000),
|
||||
(8190003, 2290007, 1, 1, 0, 2000),
|
||||
(8190003, 2290012, 1, 1, 0, 2000),
|
||||
(8190003, 2290014, 1, 1, 0, 2000),
|
||||
(8190003, 2290033, 1, 1, 0, 2000),
|
||||
(8190003, 2290045, 1, 1, 0, 2000),
|
||||
(8190003, 2290050, 1, 1, 0, 2000),
|
||||
(8190003, 2290055, 1, 1, 0, 2000),
|
||||
(8190003, 2290062, 1, 1, 0, 2000),
|
||||
(8190003, 2290063, 1, 1, 0, 2000),
|
||||
(8190003, 2290070, 1, 1, 0, 2000),
|
||||
(8190003, 2290086, 1, 1, 0, 2000),
|
||||
(8190003, 2290108, 1, 1, 0, 2000),
|
||||
(8190003, 2290133, 1, 1, 0, 6000),
|
||||
(8190004, 2290002, 1, 1, 0, 2000),
|
||||
(8190004, 2290009, 1, 1, 0, 2000),
|
||||
(8190004, 2290021, 1, 1, 0, 2000),
|
||||
(8190004, 2290034, 1, 1, 0, 2000),
|
||||
(8190004, 2290041, 1, 1, 0, 2000),
|
||||
(8190004, 2290052, 1, 1, 0, 2000),
|
||||
(8190004, 2290053, 1, 1, 0, 2000),
|
||||
(8190004, 2290058, 1, 1, 0, 2000),
|
||||
(8190004, 2290068, 1, 1, 0, 2000),
|
||||
(8190004, 2290071, 1, 1, 0, 2000),
|
||||
(8190004, 2290073, 1, 1, 0, 2000),
|
||||
(8190004, 2290090, 1, 1, 0, 2000),
|
||||
(8190004, 2290112, 1, 1, 0, 2000),
|
||||
(8190004, 2290121, 1, 1, 0, 2000),
|
||||
(8190004, 2290130, 1, 1, 0, 6000),
|
||||
(8190005, 2290000, 1, 1, 0, 2000),
|
||||
(8190005, 2290008, 1, 1, 0, 2000),
|
||||
(8190005, 2290018, 1, 1, 0, 2000),
|
||||
(8190005, 2290038, 1, 1, 0, 2000),
|
||||
(8190005, 2290060, 1, 1, 0, 2000),
|
||||
(8190005, 2290080, 1, 1, 0, 2000),
|
||||
(8190005, 2290124, 1, 1, 0, 2000),
|
||||
(8200000, 2290005, 1, 1, 0, 2000),
|
||||
(8200000, 2290011, 1, 1, 0, 2000),
|
||||
(8200000, 2290114, 1, 1, 0, 2000),
|
||||
(8200001, 2280015, 1, 1, 0, 6000),
|
||||
(8200001, 2290050, 1, 1, 0, 2000),
|
||||
(8200001, 2290059, 1, 1, 0, 2000),
|
||||
(8200001, 2290065, 1, 1, 0, 2000),
|
||||
(8200001, 2290129, 1, 1, 0, 6000),
|
||||
(8200002, 2290062, 1, 1, 0, 2000),
|
||||
(8200002, 2290066, 1, 1, 0, 2000),
|
||||
(8200002, 2290070, 1, 1, 0, 2000),
|
||||
(8200002, 2290131, 1, 1, 0, 6000),
|
||||
(8200002, 2290139, 1, 1, 0, 6000),
|
||||
(8200003, 2290012, 1, 1, 0, 2000),
|
||||
(8200003, 2290056, 1, 1, 0, 2000),
|
||||
(8200003, 2290071, 1, 1, 0, 2000),
|
||||
(8200003, 2290101, 1, 1, 0, 2000),
|
||||
(8200003, 2290136, 1, 1, 0, 6000),
|
||||
(8200004, 2280016, 1, 1, 0, 6000),
|
||||
(8200004, 2290069, 1, 1, 0, 2000),
|
||||
(8200004, 2290072, 1, 1, 0, 2000),
|
||||
(8200004, 2290073, 1, 1, 0, 2000),
|
||||
(8200004, 2290127, 1, 1, 0, 6000),
|
||||
(8200004, 2290134, 1, 1, 0, 6000),
|
||||
(8200005, 2280014, 1, 1, 0, 6000),
|
||||
(8200005, 2290078, 1, 1, 0, 2000),
|
||||
(8200005, 2290079, 1, 1, 0, 2000),
|
||||
(8200005, 2290095, 1, 1, 0, 2000),
|
||||
(8200006, 2290003, 1, 1, 0, 2000),
|
||||
(8200006, 2290064, 1, 1, 0, 2000),
|
||||
(8200006, 2290076, 1, 1, 0, 2000),
|
||||
(8200006, 2290077, 1, 1, 0, 2000),
|
||||
(8200006, 2290129, 1, 1, 0, 6000),
|
||||
(8200006, 2290138, 1, 1, 0, 6000),
|
||||
(8200007, 2290006, 1, 1, 0, 2000),
|
||||
(8200007, 2290007, 1, 1, 0, 2000),
|
||||
(8200007, 2290011, 1, 1, 0, 2000),
|
||||
(8200007, 2290016, 1, 1, 0, 2000),
|
||||
(8200007, 2290125, 1, 1, 0, 2000),
|
||||
(8200007, 2290136, 1, 1, 0, 6000),
|
||||
(8200008, 2290006, 1, 1, 0, 2000),
|
||||
(8200008, 2290051, 1, 1, 0, 2000),
|
||||
(8200008, 2290121, 1, 1, 0, 2000),
|
||||
(8200008, 2290122, 1, 1, 0, 2000),
|
||||
(8200008, 2290133, 1, 1, 0, 6000),
|
||||
(8200009, 2290013, 1, 1, 0, 2000),
|
||||
(8200009, 2290016, 1, 1, 0, 2000),
|
||||
(8200009, 2290031, 1, 1, 0, 2000),
|
||||
(8200009, 2290039, 1, 1, 0, 2000),
|
||||
(8200010, 2290026, 1, 1, 0, 2000),
|
||||
(8200010, 2290059, 1, 1, 0, 2000),
|
||||
(8200010, 2290088, 1, 1, 0, 2000),
|
||||
(8200010, 2290089, 1, 1, 0, 2000),
|
||||
(8200010, 2290127, 1, 1, 0, 6000),
|
||||
(8200011, 2290001, 1, 1, 0, 3000),
|
||||
(8200011, 2290040, 1, 1, 0, 3000),
|
||||
(8200011, 2290046, 1, 1, 0, 3000),
|
||||
(8200011, 2290048, 1, 1, 0, 3000),
|
||||
(8200011, 2290049, 1, 1, 0, 3000),
|
||||
(8200011, 2290114, 1, 1, 0, 3000),
|
||||
(8200011, 2290137, 1, 1, 0, 9000),
|
||||
(8200012, 2290041, 1, 1, 0, 3000),
|
||||
(8200012, 2290092, 1, 1, 0, 3000),
|
||||
(8200012, 2290093, 1, 1, 0, 3000),
|
||||
(8200012, 2290115, 1, 1, 0, 3000),
|
||||
(8200012, 2290137, 1, 1, 0, 9000),
|
||||
(8200012, 2290139, 1, 1, 0, 9000),
|
||||
(8220002, 2290020, 1, 1, 0, 40000),
|
||||
(8220002, 2290081, 1, 1, 0, 40000),
|
||||
(8220002, 2290085, 1, 1, 0, 40000),
|
||||
(8220002, 2290133, 1, 1, 0, 120000),
|
||||
(8220003, 2290006, 1, 1, 0, 40000),
|
||||
(8220003, 2290030, 1, 1, 0, 40000),
|
||||
(8220003, 2290031, 1, 1, 0, 40000),
|
||||
(8220003, 2290032, 1, 1, 0, 40000),
|
||||
(8220003, 2290033, 1, 1, 0, 40000),
|
||||
(8220003, 2290060, 1, 1, 0, 40000),
|
||||
(8220003, 2290061, 1, 1, 0, 40000),
|
||||
(8220003, 2290076, 1, 1, 0, 40000),
|
||||
(8220003, 2290077, 1, 1, 0, 40000),
|
||||
(8220003, 2290104, 1, 1, 0, 40000),
|
||||
(8220003, 2290105, 1, 1, 0, 40000),
|
||||
(8220003, 2290117, 1, 1, 0, 40000),
|
||||
(8220003, 2290118, 1, 1, 0, 40000),
|
||||
(8220004, 2290018, 1, 1, 0, 40000),
|
||||
(8220004, 2290019, 1, 1, 0, 40000),
|
||||
(8220004, 2290024, 1, 1, 0, 40000),
|
||||
(8220004, 2290025, 1, 1, 0, 40000),
|
||||
(8220004, 2290058, 1, 1, 0, 40000),
|
||||
(8220004, 2290059, 1, 1, 0, 40000),
|
||||
(8220004, 2290076, 1, 1, 0, 40000),
|
||||
(8220004, 2290077, 1, 1, 0, 40000),
|
||||
(8220004, 2290106, 1, 1, 0, 40000),
|
||||
(8220004, 2290127, 1, 1, 0, 120000),
|
||||
(8220004, 2290134, 1, 1, 0, 120000),
|
||||
(8220005, 2290002, 1, 1, 0, 60000),
|
||||
(8220005, 2290003, 1, 1, 0, 60000),
|
||||
(8220005, 2290036, 1, 1, 0, 60000),
|
||||
(8220005, 2290037, 1, 1, 0, 60000),
|
||||
(8220005, 2290055, 1, 1, 0, 60000),
|
||||
(8220005, 2290080, 1, 1, 0, 60000),
|
||||
(8220005, 2290099, 1, 1, 0, 60000),
|
||||
(8220005, 2290131, 1, 1, 0, 180000),
|
||||
(8220005, 2290136, 1, 1, 0, 180000),
|
||||
(8220006, 2290012, 1, 1, 0, 80000),
|
||||
(8220006, 2290013, 1, 1, 0, 80000),
|
||||
(8220006, 2290042, 1, 1, 0, 80000),
|
||||
(8220006, 2290043, 1, 1, 0, 80000),
|
||||
(8220006, 2290060, 1, 1, 0, 80000),
|
||||
(8220006, 2290061, 1, 1, 0, 80000),
|
||||
(8220006, 2290090, 1, 1, 0, 80000),
|
||||
(8220006, 2290119, 1, 1, 0, 80000),
|
||||
(8220006, 2290120, 1, 1, 0, 80000),
|
||||
(8220006, 2290135, 1, 1, 0, 240000),
|
||||
(8220006, 2290138, 1, 1, 0, 240000),
|
||||
(8220007, 2290035, 1, 1, 0, 40000),
|
||||
(8220007, 2290091, 1, 1, 0, 40000),
|
||||
(8220007, 2290108, 1, 1, 0, 40000),
|
||||
(8220009, 2290031, 1, 1, 0, 40000),
|
||||
(8220009, 2290129, 1, 1, 0, 120000),
|
||||
(8220015, 2280004, 1, 1, 0, 40000),
|
||||
(8220015, 2280005, 1, 1, 0, 40000),
|
||||
(8220015, 2280006, 1, 1, 0, 40000),
|
||||
(8500002, 2280007, 1, 1, 0, 60000),
|
||||
(8500002, 2280008, 1, 1, 0, 60000),
|
||||
(8500002, 2280009, 1, 1, 0, 60000),
|
||||
(8500002, 2280010, 1, 1, 0, 60000),
|
||||
(8500002, 2290006, 1, 1, 0, 60000),
|
||||
(8500002, 2290010, 1, 1, 0, 60000),
|
||||
(8500002, 2290011, 1, 1, 0, 60000),
|
||||
(8500002, 2290013, 1, 1, 0, 60000),
|
||||
(8500002, 2290028, 1, 1, 0, 60000),
|
||||
(8500002, 2290037, 1, 1, 0, 60000),
|
||||
(8500002, 2290043, 1, 1, 0, 60000),
|
||||
(8500002, 2290051, 1, 1, 0, 60000),
|
||||
(8500002, 2290056, 1, 1, 0, 60000),
|
||||
(8500002, 2290061, 1, 1, 0, 60000),
|
||||
(8500002, 2290066, 1, 1, 0, 60000),
|
||||
(8500002, 2290071, 1, 1, 0, 60000),
|
||||
(8500002, 2290078, 1, 1, 0, 60000),
|
||||
(8500002, 2290089, 1, 1, 0, 60000),
|
||||
(8500002, 2290091, 1, 1, 0, 60000),
|
||||
(8500002, 2290104, 1, 1, 0, 60000),
|
||||
(8500002, 2290107, 1, 1, 0, 60000),
|
||||
(8500002, 2290121, 1, 1, 0, 60000),
|
||||
(8500002, 2290123, 1, 1, 0, 60000),
|
||||
(8500002, 2290126, 1, 1, 0, 180000),
|
||||
(8500002, 2290129, 1, 1, 0, 180000),
|
||||
(8510000, 2280007, 1, 1, 0, 40000),
|
||||
(8510000, 2280008, 1, 1, 0, 40000),
|
||||
(8510000, 2280009, 1, 1, 0, 40000),
|
||||
(8510000, 2280010, 1, 1, 0, 40000),
|
||||
(8510000, 2290000, 1, 1, 0, 40000),
|
||||
(8510000, 2290001, 1, 1, 0, 40000),
|
||||
(8510000, 2290004, 1, 1, 0, 40000),
|
||||
(8510000, 2290005, 1, 1, 0, 40000),
|
||||
(8510000, 2290024, 1, 1, 0, 40000),
|
||||
(8510000, 2290025, 1, 1, 0, 40000),
|
||||
(8510000, 2290026, 1, 1, 0, 40000),
|
||||
(8510000, 2290027, 1, 1, 0, 40000),
|
||||
(8510000, 2290052, 1, 1, 0, 40000),
|
||||
(8510000, 2290053, 1, 1, 0, 40000),
|
||||
(8510000, 2290054, 1, 1, 0, 40000),
|
||||
(8510000, 2290055, 1, 1, 0, 40000),
|
||||
(8510000, 2290076, 1, 1, 0, 40000),
|
||||
(8510000, 2290077, 1, 1, 0, 40000),
|
||||
(8510000, 2290082, 1, 1, 0, 40000),
|
||||
(8510000, 2290083, 1, 1, 0, 40000),
|
||||
(8510000, 2290097, 1, 1, 0, 40000),
|
||||
(8510000, 2290099, 1, 1, 0, 40000),
|
||||
(8510000, 2290106, 1, 1, 0, 40000),
|
||||
(8510000, 2290108, 1, 1, 0, 40000),
|
||||
(8510000, 2290112, 1, 1, 0, 40000),
|
||||
(8510000, 2290114, 1, 1, 0, 40000),
|
||||
(8510000, 2290122, 1, 1, 0, 40000),
|
||||
(8510000, 2290124, 1, 1, 0, 40000),
|
||||
(8510000, 2290132, 1, 1, 0, 120000),
|
||||
(8520000, 2280007, 1, 1, 0, 40000),
|
||||
(8520000, 2280008, 1, 1, 0, 40000),
|
||||
(8520000, 2280009, 1, 1, 0, 40000),
|
||||
(8520000, 2280010, 1, 1, 0, 40000),
|
||||
(8520000, 2290000, 1, 1, 0, 40000),
|
||||
(8520000, 2290001, 1, 1, 0, 40000),
|
||||
(8520000, 2290004, 1, 1, 0, 40000),
|
||||
(8520000, 2290005, 1, 1, 0, 40000),
|
||||
(8520000, 2290024, 1, 1, 0, 40000),
|
||||
(8520000, 2290025, 1, 1, 0, 40000),
|
||||
(8520000, 2290026, 1, 1, 0, 40000),
|
||||
(8520000, 2290027, 1, 1, 0, 40000),
|
||||
(8520000, 2290052, 1, 1, 0, 40000),
|
||||
(8520000, 2290053, 1, 1, 0, 40000),
|
||||
(8520000, 2290054, 1, 1, 0, 40000),
|
||||
(8520000, 2290055, 1, 1, 0, 40000),
|
||||
(8520000, 2290076, 1, 1, 0, 40000),
|
||||
(8520000, 2290077, 1, 1, 0, 40000),
|
||||
(8520000, 2290082, 1, 1, 0, 40000),
|
||||
(8520000, 2290083, 1, 1, 0, 40000),
|
||||
(8520000, 2290097, 1, 1, 0, 40000),
|
||||
(8520000, 2290099, 1, 1, 0, 40000),
|
||||
(8520000, 2290106, 1, 1, 0, 40000),
|
||||
(8520000, 2290108, 1, 1, 0, 40000),
|
||||
(8520000, 2290112, 1, 1, 0, 40000),
|
||||
(8520000, 2290114, 1, 1, 0, 40000),
|
||||
(8520000, 2290122, 1, 1, 0, 40000),
|
||||
(8520000, 2290124, 1, 1, 0, 40000),
|
||||
(8520000, 2290132, 1, 1, 0, 120000),
|
||||
(8800002, 2280007, 1, 1, 0, 80000),
|
||||
(8800002, 2280008, 1, 1, 0, 80000),
|
||||
(8800002, 2280009, 1, 1, 0, 80000),
|
||||
(8800002, 2280010, 1, 1, 0, 80000),
|
||||
(8800002, 2280013, 1, 1, 0, 240000),
|
||||
(8800002, 2280014, 1, 1, 0, 240000),
|
||||
(8800002, 2280015, 1, 1, 0, 240000),
|
||||
(8800002, 2280016, 1, 1, 0, 240000),
|
||||
(8800002, 2290006, 1, 1, 0, 80000),
|
||||
(8800002, 2290007, 1, 1, 0, 80000),
|
||||
(8800002, 2290016, 1, 1, 0, 80000),
|
||||
(8800002, 2290020, 1, 1, 0, 80000),
|
||||
(8800002, 2290022, 1, 1, 0, 80000),
|
||||
(8800002, 2290024, 1, 1, 0, 80000),
|
||||
(8800002, 2290028, 1, 1, 0, 80000),
|
||||
(8800002, 2290029, 1, 1, 0, 80000),
|
||||
(8800002, 2290040, 1, 1, 0, 80000),
|
||||
(8800002, 2290046, 1, 1, 0, 80000),
|
||||
(8800002, 2290048, 1, 1, 0, 80000),
|
||||
(8800002, 2290056, 1, 1, 0, 80000),
|
||||
(8800002, 2290057, 1, 1, 0, 80000),
|
||||
(8800002, 2290058, 1, 1, 0, 80000),
|
||||
(8800002, 2290064, 1, 1, 0, 80000),
|
||||
(8800002, 2290067, 1, 1, 0, 80000),
|
||||
(8800002, 2290074, 1, 1, 0, 80000),
|
||||
(8800002, 2290079, 1, 1, 0, 80000),
|
||||
(8800002, 2290084, 1, 1, 0, 80000),
|
||||
(8800002, 2290094, 1, 1, 0, 80000),
|
||||
(8800002, 2290110, 1, 1, 0, 80000),
|
||||
(8800002, 2290115, 1, 1, 0, 80000),
|
||||
(8810018, 2290017, 1, 1, 0, 100000),
|
||||
(8810018, 2290021, 1, 1, 0, 100000),
|
||||
(8810018, 2290023, 1, 1, 0, 100000),
|
||||
(8810018, 2290041, 1, 1, 0, 100000),
|
||||
(8810018, 2290047, 1, 1, 0, 100000),
|
||||
(8810018, 2290049, 1, 1, 0, 100000),
|
||||
(8810018, 2290065, 1, 1, 0, 100000),
|
||||
(8810018, 2290075, 1, 1, 0, 100000),
|
||||
(8810018, 2290085, 1, 1, 0, 100000),
|
||||
(8810018, 2290095, 1, 1, 0, 100000),
|
||||
(8810018, 2290096, 1, 1, 0, 100000),
|
||||
(8810018, 2290111, 1, 1, 0, 100000),
|
||||
(8810018, 2290116, 1, 1, 0, 100000),
|
||||
(8810018, 2290125, 1, 1, 0, 100000),
|
||||
(8810018, 2290133, 1, 1, 0, 300000),
|
||||
(8810018, 2290137, 1, 1, 0, 300000),
|
||||
(8810018, 2290139, 1, 1, 0, 300000),
|
||||
(8820000, 2290010, 1, 1, 0, 120000),
|
||||
(8820000, 2290022, 1, 1, 0, 120000),
|
||||
(8820000, 2290040, 1, 1, 0, 120000),
|
||||
(8820000, 2290046, 1, 1, 0, 120000),
|
||||
(8820000, 2290048, 1, 1, 0, 120000),
|
||||
(8820000, 2290052, 1, 1, 0, 120000),
|
||||
(8820000, 2290084, 1, 1, 0, 120000),
|
||||
(8820000, 2290090, 1, 1, 0, 120000),
|
||||
(8820000, 2290106, 1, 1, 0, 120000),
|
||||
(8820000, 2290119, 1, 1, 0, 120000),
|
||||
(8820001, 2290010, 1, 1, 0, 120000),
|
||||
(8820001, 2290022, 1, 1, 0, 120000),
|
||||
(8820001, 2290040, 1, 1, 0, 120000),
|
||||
(8820001, 2290046, 1, 1, 0, 120000),
|
||||
(8820001, 2290048, 1, 1, 0, 120000),
|
||||
(8820001, 2290052, 1, 1, 0, 120000),
|
||||
(8820001, 2290084, 1, 1, 0, 120000),
|
||||
(8820001, 2290090, 1, 1, 0, 120000),
|
||||
(8820001, 2290106, 1, 1, 0, 120000),
|
||||
(8820001, 2290119, 1, 1, 0, 120000),
|
||||
(9300028, 2280015, 1, 1, 0, 120000),
|
||||
(9300028, 2290026, 1, 1, 0, 40000),
|
||||
(9300028, 2290064, 1, 1, 0, 40000),
|
||||
(9300028, 2290075, 1, 1, 0, 40000),
|
||||
(9300028, 2290093, 1, 1, 0, 40000),
|
||||
(9300028, 2290111, 1, 1, 0, 40000),
|
||||
(9300094, 2280004, 1, 1, 0, 40000),
|
||||
(9300094, 2280005, 1, 1, 0, 40000),
|
||||
(9300094, 2280006, 1, 1, 0, 40000),
|
||||
(9300095, 2280004, 1, 1, 0, 2000),
|
||||
(9300095, 2280005, 1, 1, 0, 2000),
|
||||
(9300095, 2280006, 1, 1, 0, 2000),
|
||||
(9303016, 2290006, 1, 1, 0, 2000),
|
||||
(9303016, 2290030, 1, 1, 0, 2000),
|
||||
(9303016, 2290032, 1, 1, 0, 2000),
|
||||
(9303016, 2290060, 1, 1, 0, 2000),
|
||||
(9303016, 2290076, 1, 1, 0, 2000),
|
||||
(9303016, 2290104, 1, 1, 0, 2000),
|
||||
(9303016, 2290117, 1, 1, 0, 2000),
|
||||
(9400014, 2290053, 1, 1, 0, 40000),
|
||||
(9400014, 2290087, 1, 1, 0, 40000),
|
||||
(9400014, 2290112, 1, 1, 0, 40000),
|
||||
(9400014, 2290122, 1, 1, 0, 40000),
|
||||
(9400120, 2290045, 1, 1, 0, 40000),
|
||||
(9400121, 2280014, 1, 1, 0, 180000),
|
||||
(9400121, 2290081, 1, 1, 0, 60000),
|
||||
(9400121, 2290087, 1, 1, 0, 60000),
|
||||
(9400121, 2290101, 1, 1, 0, 60000),
|
||||
(9400121, 2290103, 1, 1, 0, 60000),
|
||||
(9400122, 2290007, 1, 1, 0, 40000),
|
||||
(9400122, 2290062, 1, 1, 0, 40000),
|
||||
(9400122, 2290116, 1, 1, 0, 40000),
|
||||
(9400300, 2290045, 1, 1, 0, 120000),
|
||||
(9400300, 2290055, 1, 1, 0, 120000),
|
||||
(9400300, 2290063, 1, 1, 0, 120000),
|
||||
(9400300, 2290079, 1, 1, 0, 120000),
|
||||
(9400300, 2290081, 1, 1, 0, 120000),
|
||||
(9400300, 2290096, 1, 1, 0, 120000),
|
||||
(9400514, 2290023, 1, 1, 0, 40000),
|
||||
(9400514, 2290057, 1, 1, 0, 40000),
|
||||
(9400514, 2290088, 1, 1, 0, 40000),
|
||||
(9400514, 2290095, 1, 1, 0, 40000),
|
||||
(9400514, 2290115, 1, 1, 0, 40000),
|
||||
(9400514, 2290139, 1, 1, 0, 120000),
|
||||
(9400549, 2290001, 1, 1, 0, 40000),
|
||||
(9400549, 2290020, 1, 1, 0, 40000),
|
||||
(9400549, 2290045, 1, 1, 0, 40000),
|
||||
(9400549, 2290057, 1, 1, 0, 40000),
|
||||
(9400549, 2290086, 1, 1, 0, 40000),
|
||||
(9400575, 2290009, 1, 1, 0, 40000),
|
||||
(9400575, 2290051, 1, 1, 0, 40000),
|
||||
(9400575, 2290081, 1, 1, 0, 40000),
|
||||
(9400575, 2290087, 1, 1, 0, 40000),
|
||||
(9400575, 2290107, 1, 1, 0, 40000),
|
||||
(9400575, 2290123, 1, 1, 0, 40000),
|
||||
(9400580, 2290004, 1, 1, 0, 2000),
|
||||
(9400580, 2290024, 1, 1, 0, 2000),
|
||||
(9400580, 2290083, 1, 1, 0, 2000),
|
||||
(9400580, 2290087, 1, 1, 0, 2000),
|
||||
(9400580, 2290103, 1, 1, 0, 2000),
|
||||
(9400580, 2290121, 1, 1, 0, 2000),
|
||||
(9400582, 2290005, 1, 1, 0, 2000),
|
||||
(9400582, 2290010, 1, 1, 0, 2000),
|
||||
(9400582, 2290029, 1, 1, 0, 2000),
|
||||
(9400582, 2290047, 1, 1, 0, 2000),
|
||||
(9400582, 2290049, 1, 1, 0, 2000),
|
||||
(9400582, 2290074, 1, 1, 0, 2000),
|
||||
(9400582, 2290079, 1, 1, 0, 2000),
|
||||
(9400582, 2290081, 1, 1, 0, 2000),
|
||||
(9400582, 2290135, 1, 1, 0, 6000),
|
||||
(9400590, 2290088, 1, 1, 0, 60000),
|
||||
(9400590, 2290125, 1, 1, 0, 60000),
|
||||
(9400590, 2290135, 1, 1, 0, 180000),
|
||||
(9400591, 2290039, 1, 1, 0, 60000),
|
||||
(9400591, 2290074, 1, 1, 0, 60000),
|
||||
(9400591, 2290113, 1, 1, 0, 60000),
|
||||
(9400592, 2290047, 1, 1, 0, 60000),
|
||||
(9400592, 2290123, 1, 1, 0, 60000),
|
||||
(9400592, 2290131, 1, 1, 0, 180000),
|
||||
(9400593, 2290069, 1, 1, 0, 60000),
|
||||
(9400593, 2290093, 1, 1, 0, 60000),
|
||||
(9400593, 2290138, 1, 1, 0, 180000),
|
||||
(9420513, 2290039, 1, 1, 0, 40000),
|
||||
(9420513, 2290100, 1, 1, 0, 40000),
|
||||
(9420513, 2290108, 1, 1, 0, 40000),
|
||||
(9420513, 2290118, 1, 1, 0, 40000),
|
||||
(9420513, 2290138, 1, 1, 0, 120000),
|
||||
(9420514, 2290099, 1, 1, 0, 1287),
|
||||
(9420517, 2290000, 1, 1, 0, 1287),
|
||||
(9420517, 2290008, 1, 1, 0, 1287),
|
||||
(9420517, 2290018, 1, 1, 0, 1287),
|
||||
(9420517, 2290038, 1, 1, 0, 1287),
|
||||
(9420517, 2290060, 1, 1, 0, 1287),
|
||||
(9420517, 2290080, 1, 1, 0, 1287),
|
||||
(9420517, 2290103, 1, 1, 0, 1287),
|
||||
(9420518, 2290123, 1, 1, 0, 1287),
|
||||
(9420519, 2290113, 1, 1, 0, 1287),
|
||||
(9420522, 2290000, 1, 1, 0, 1287),
|
||||
(9420522, 2290001, 1, 1, 0, 1287),
|
||||
(9420522, 2290011, 1, 1, 0, 1287),
|
||||
(9420522, 2290025, 1, 1, 0, 1287),
|
||||
(9420522, 2290028, 1, 1, 0, 1287),
|
||||
(9420522, 2290037, 1, 1, 0, 1287),
|
||||
(9420522, 2290043, 1, 1, 0, 1287),
|
||||
(9420522, 2290066, 1, 1, 0, 1287),
|
||||
(9420522, 2290082, 1, 1, 0, 1287),
|
||||
(9420522, 2290083, 1, 1, 0, 1287),
|
||||
(9420522, 2290089, 1, 1, 0, 1287),
|
||||
(9420522, 2290091, 1, 1, 0, 1287),
|
||||
(9420522, 2290107, 1, 1, 0, 1287),
|
||||
(9420540, 2280006, 1, 1, 0, 2000),
|
||||
(9420540, 2290119, 1, 1, 0, 2000),
|
||||
(9420540, 2290120, 1, 1, 0, 2000),
|
||||
(9420544, 2280007, 1, 1, 0, 80000),
|
||||
(9420544, 2280008, 1, 1, 0, 80000),
|
||||
(9420544, 2280009, 1, 1, 0, 80000),
|
||||
(9420544, 2280010, 1, 1, 0, 80000),
|
||||
(9420544, 2290002, 1, 1, 0, 80000),
|
||||
(9420544, 2290015, 1, 1, 0, 80000),
|
||||
(9420544, 2290022, 1, 1, 0, 80000),
|
||||
(9420544, 2290027, 1, 1, 0, 80000),
|
||||
(9420544, 2290034, 1, 1, 0, 80000),
|
||||
(9420544, 2290052, 1, 1, 0, 80000),
|
||||
(9420544, 2290054, 1, 1, 0, 80000),
|
||||
(9420544, 2290089, 1, 1, 0, 80000),
|
||||
(9420544, 2290094, 1, 1, 0, 80000),
|
||||
(9420544, 2290098, 1, 1, 0, 80000),
|
||||
(9420544, 2290105, 1, 1, 0, 80000),
|
||||
(9420544, 2290110, 1, 1, 0, 80000),
|
||||
(9420544, 2290119, 1, 1, 0, 80000),
|
||||
(9420549, 2280007, 1, 1, 0, 80000),
|
||||
(9420549, 2280008, 1, 1, 0, 80000),
|
||||
(9420549, 2280009, 1, 1, 0, 80000),
|
||||
(9420549, 2280010, 1, 1, 0, 80000),
|
||||
(9420549, 2290002, 1, 1, 0, 80000),
|
||||
(9420549, 2290015, 1, 1, 0, 80000),
|
||||
(9420549, 2290022, 1, 1, 0, 80000),
|
||||
(9420549, 2290027, 1, 1, 0, 80000),
|
||||
(9420549, 2290034, 1, 1, 0, 80000),
|
||||
(9420549, 2290052, 1, 1, 0, 80000),
|
||||
(9420549, 2290054, 1, 1, 0, 80000),
|
||||
(9420549, 2290089, 1, 1, 0, 80000),
|
||||
(9420549, 2290094, 1, 1, 0, 80000),
|
||||
(9420549, 2290098, 1, 1, 0, 80000),
|
||||
(9420549, 2290105, 1, 1, 0, 80000),
|
||||
(9420549, 2290110, 1, 1, 0, 80000),
|
||||
(9420549, 2290119, 1, 1, 0, 80000),
|
||||
(9500166, 2290044, 1, 1, 0, 2000),
|
||||
(9500173, 2290018, 1, 1, 0, 40000),
|
||||
(9500173, 2290019, 1, 1, 0, 40000),
|
||||
(9500173, 2290032, 1, 1, 0, 40000),
|
||||
(9500173, 2290042, 1, 1, 0, 40000),
|
||||
(9500173, 2290058, 1, 1, 0, 40000),
|
||||
(9500173, 2290068, 1, 1, 0, 40000),
|
||||
(9500173, 2290072, 1, 1, 0, 40000),
|
||||
(9500173, 2290092, 1, 1, 0, 40000),
|
||||
(9500173, 2290099, 1, 1, 0, 40000),
|
||||
(9500173, 2290102, 1, 1, 0, 40000),
|
||||
(9500173, 2290119, 1, 1, 0, 40000),
|
||||
(9500173, 2290128, 1, 1, 0, 120000),
|
||||
(9500174, 2290002, 1, 1, 0, 40000),
|
||||
(9500174, 2290014, 1, 1, 0, 40000),
|
||||
(9500174, 2290030, 1, 1, 0, 40000),
|
||||
(9500174, 2290080, 1, 1, 0, 40000),
|
||||
(9500174, 2290130, 1, 1, 0, 120000),
|
||||
(9500180, 2290010, 1, 1, 0, 40000),
|
||||
(9500180, 2290028, 1, 1, 0, 40000),
|
||||
(9500180, 2290126, 1, 1, 0, 120000),
|
||||
(9500181, 2290010, 1, 1, 0, 40000),
|
||||
(9500181, 2290028, 1, 1, 0, 40000),
|
||||
(9500181, 2290126, 1, 1, 0, 120000),
|
||||
(9500331, 2290010, 1, 1, 0, 40000),
|
||||
(9500331, 2290028, 1, 1, 0, 40000),
|
||||
(9500331, 2290126, 1, 1, 0, 120000),
|
||||
(9500332, 2290132, 1, 1, 0, 120000),
|
||||
(9500333, 2290006, 1, 1, 0, 40000),
|
||||
(9500333, 2290030, 1, 1, 0, 40000),
|
||||
(9500333, 2290032, 1, 1, 0, 40000),
|
||||
(9500333, 2290060, 1, 1, 0, 40000),
|
||||
(9500333, 2290076, 1, 1, 0, 40000),
|
||||
(9500333, 2290104, 1, 1, 0, 40000),
|
||||
(9500333, 2290117, 1, 1, 0, 40000),
|
||||
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=661885c2
|
||||
build.xml.script.CRC32=5e98558c
|
||||
build.xml.stylesheet.CRC32=[email protected]
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=661885c2
|
||||
nbproject/build-impl.xml.script.CRC32=73de760b
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=[email protected]
|
||||
@@ -0,0 +1,77 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
application.title=MapleSkillbookChanceFetcher
|
||||
application.vendor=USER
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# Os arquivos em build.classes.dir que devem ser exclu\u00eddos do jar de distribui\u00e7\u00e3o
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/MapleSkillbookChanceFetcher.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
endorsed.classpath=
|
||||
excludes=
|
||||
file.reference.mysql-connector-java-bin.jar=lib/mysql-connector-java-bin.jar
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=\
|
||||
${file.reference.mysql-connector-java-bin.jar}
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=1.7
|
||||
javac.target=1.7
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
main.class=mapleskillbookchancefetcher.MapleSkillbookChanceFetcher
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=JDK_1.7
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>MapleSkillbookChanceFetcher</name>
|
||||
<explicit-platform explicit-source-supported="true"/>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 life;
|
||||
|
||||
public enum Element {
|
||||
NEUTRAL, FIRE, ICE, LIGHTING, POISON, HOLY, DARK;
|
||||
|
||||
public static Element getFromChar(char c) {
|
||||
switch (Character.toUpperCase(c)) {
|
||||
case 'F':
|
||||
return FIRE;
|
||||
case 'I':
|
||||
return ICE;
|
||||
case 'L':
|
||||
return LIGHTING;
|
||||
case 'S':
|
||||
return POISON;
|
||||
case 'H':
|
||||
return HOLY;
|
||||
case 'D':
|
||||
return DARK;
|
||||
case 'P':
|
||||
return NEUTRAL;
|
||||
}
|
||||
throw new IllegalArgumentException("unknown elemnt char " + c);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 life;
|
||||
|
||||
public enum ElementalEffectiveness {
|
||||
NORMAL, IMMUNE, STRONG, WEAK, NEUTRAL;
|
||||
|
||||
public static ElementalEffectiveness getByNumber(int num) {
|
||||
switch (num) {
|
||||
case 1:
|
||||
return IMMUNE;
|
||||
case 2:
|
||||
return STRONG;
|
||||
case 3:
|
||||
return WEAK;
|
||||
case 4:
|
||||
return NEUTRAL;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unkown effectiveness: " + num);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 life;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataDirectoryEntry;
|
||||
import provider.MapleDataFileEntry;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import provider.wz.MapleDataType;
|
||||
import tools.Pair;
|
||||
|
||||
public class MapleLifeFactory {
|
||||
private static String wzPath = "../../wz";
|
||||
private static MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(wzPath + "/Mob.wz"));
|
||||
private final static MapleDataProvider stringDataWZ = MapleDataProviderFactory.getDataProvider(new File(wzPath + "/String.wz"));
|
||||
private static MapleData mobStringData = stringDataWZ.getData("Mob.img");
|
||||
private static MapleData npcStringData = stringDataWZ.getData("Npc.img");
|
||||
private static Map<Integer, MapleMonsterStats> monsterStats = new HashMap<>();
|
||||
|
||||
private static int getMonsterId(String fileName) {
|
||||
return Integer.parseInt(fileName.substring(0, 7));
|
||||
}
|
||||
|
||||
public static Map<Integer, MapleMonsterStats> getAllMonsterStats() {
|
||||
MapleDataDirectoryEntry root = data.getRoot();
|
||||
|
||||
System.out.print("Parsing mob stats... ");
|
||||
for (MapleDataFileEntry mFile : root.getFiles()) {
|
||||
try {
|
||||
String fileName = mFile.getName();
|
||||
|
||||
//System.out.println("Parsing '" + fileName + "'");
|
||||
MapleData monsterData = data.getData(fileName);
|
||||
if (monsterData == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer mid = getMonsterId(fileName);
|
||||
|
||||
MapleData monsterInfoData = monsterData.getChildByPath("info");
|
||||
MapleMonsterStats stats = new MapleMonsterStats();
|
||||
stats.setHp(MapleDataTool.getIntConvert("maxHP", monsterInfoData));
|
||||
stats.setFriendly(MapleDataTool.getIntConvert("damagedByMob", monsterInfoData, 0) == 1);
|
||||
stats.setPADamage(MapleDataTool.getIntConvert("PADamage", monsterInfoData));
|
||||
stats.setPDDamage(MapleDataTool.getIntConvert("PDDamage", monsterInfoData));
|
||||
stats.setMADamage(MapleDataTool.getIntConvert("MADamage", monsterInfoData));
|
||||
stats.setMDDamage(MapleDataTool.getIntConvert("MDDamage", monsterInfoData));
|
||||
stats.setMp(MapleDataTool.getIntConvert("maxMP", monsterInfoData, 0));
|
||||
stats.setExp(MapleDataTool.getIntConvert("exp", monsterInfoData, 0));
|
||||
stats.setLevel(MapleDataTool.getIntConvert("level", monsterInfoData));
|
||||
stats.setRemoveAfter(MapleDataTool.getIntConvert("removeAfter", monsterInfoData, 0));
|
||||
stats.setBoss(MapleDataTool.getIntConvert("boss", monsterInfoData, 0) > 0);
|
||||
stats.setExplosiveReward(MapleDataTool.getIntConvert("explosiveReward", monsterInfoData, 0) > 0);
|
||||
stats.setFfaLoot(MapleDataTool.getIntConvert("publicReward", monsterInfoData, 0) > 0);
|
||||
stats.setUndead(MapleDataTool.getIntConvert("undead", monsterInfoData, 0) > 0);
|
||||
stats.setName(MapleDataTool.getString(mid + "/name", mobStringData, "MISSINGNO"));
|
||||
stats.setBuffToGive(MapleDataTool.getIntConvert("buff", monsterInfoData, -1));
|
||||
stats.setCP(MapleDataTool.getIntConvert("getCP", monsterInfoData, 0));
|
||||
stats.setRemoveOnMiss(MapleDataTool.getIntConvert("removeOnMiss", monsterInfoData, 0) > 0);
|
||||
|
||||
MapleData special = monsterInfoData.getChildByPath("coolDamage");
|
||||
if (special != null) {
|
||||
int coolDmg = MapleDataTool.getIntConvert("coolDamage", monsterInfoData);
|
||||
int coolProb = MapleDataTool.getIntConvert("coolDamageProb", monsterInfoData, 0);
|
||||
stats.setCool(new Pair<>(coolDmg, coolProb));
|
||||
}
|
||||
special = monsterInfoData.getChildByPath("loseItem");
|
||||
if (special != null) {
|
||||
for (MapleData liData : special.getChildren()) {
|
||||
stats.addLoseItem(new loseItem(MapleDataTool.getInt(liData.getChildByPath("id")), (byte) MapleDataTool.getInt(liData.getChildByPath("prop")), (byte) MapleDataTool.getInt(liData.getChildByPath("x"))));
|
||||
}
|
||||
}
|
||||
special = monsterInfoData.getChildByPath("selfDestruction");
|
||||
if (special != null) {
|
||||
stats.setSelfDestruction(new selfDestruction((byte) MapleDataTool.getInt(special.getChildByPath("action")), MapleDataTool.getIntConvert("removeAfter", special, -1), MapleDataTool.getIntConvert("hp", special, -1)));
|
||||
}
|
||||
MapleData firstAttackData = monsterInfoData.getChildByPath("firstAttack");
|
||||
int firstAttack = 0;
|
||||
if (firstAttackData != null) {
|
||||
if (firstAttackData.getType() == MapleDataType.FLOAT) {
|
||||
firstAttack = Math.round(MapleDataTool.getFloat(firstAttackData));
|
||||
} else {
|
||||
firstAttack = MapleDataTool.getInt(firstAttackData);
|
||||
}
|
||||
}
|
||||
stats.setFirstAttack(firstAttack > 0);
|
||||
stats.setDropPeriod(MapleDataTool.getIntConvert("dropItemPeriod", monsterInfoData, 0) * 10000);
|
||||
|
||||
stats.setTagColor(MapleDataTool.getIntConvert("hpTagColor", monsterInfoData, 0));
|
||||
stats.setTagBgColor(MapleDataTool.getIntConvert("hpTagBgcolor", monsterInfoData, 0));
|
||||
|
||||
for (MapleData idata : monsterData) {
|
||||
if (!idata.getName().equals("info")) {
|
||||
int delay = 0;
|
||||
for (MapleData pic : idata.getChildren()) {
|
||||
delay += MapleDataTool.getIntConvert("delay", pic, 0);
|
||||
}
|
||||
stats.setAnimationTime(idata.getName(), delay);
|
||||
}
|
||||
}
|
||||
MapleData reviveInfo = monsterInfoData.getChildByPath("revive");
|
||||
if (reviveInfo != null) {
|
||||
List<Integer> revives = new LinkedList<>();
|
||||
for (MapleData data_ : reviveInfo) {
|
||||
revives.add(MapleDataTool.getInt(data_));
|
||||
}
|
||||
stats.setRevives(revives);
|
||||
}
|
||||
decodeElementalString(stats, MapleDataTool.getString("elemAttr", monsterInfoData, ""));
|
||||
MapleData monsterSkillData = monsterInfoData.getChildByPath("skill");
|
||||
if (monsterSkillData != null) {
|
||||
int i = 0;
|
||||
List<Pair<Integer, Integer>> skills = new ArrayList<>();
|
||||
while (monsterSkillData.getChildByPath(Integer.toString(i)) != null) {
|
||||
skills.add(new Pair<>(Integer.valueOf(MapleDataTool.getInt(i + "/skill", monsterSkillData, 0)), Integer.valueOf(MapleDataTool.getInt(i + "/level", monsterSkillData, 0))));
|
||||
i++;
|
||||
}
|
||||
stats.setSkills(skills);
|
||||
}
|
||||
MapleData banishData = monsterInfoData.getChildByPath("ban");
|
||||
if (banishData != null) {
|
||||
stats.setBanishInfo(new BanishInfo(MapleDataTool.getString("banMsg", banishData), MapleDataTool.getInt("banMap/0/field", banishData, -1), MapleDataTool.getString("banMap/0/portal", banishData, "sp")));
|
||||
}
|
||||
|
||||
monsterStats.put(mid, stats);
|
||||
} catch(NullPointerException npe) {
|
||||
//System.out.println("[SEVERE] " + mFile.getName() + " failed to load. Issue: " + npe.getMessage() + "\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("done!");
|
||||
return monsterStats;
|
||||
}
|
||||
|
||||
private static void decodeElementalString(MapleMonsterStats stats, String elemAttr) {
|
||||
for (int i = 0; i < elemAttr.length(); i += 2) {
|
||||
stats.setEffectiveness(Element.getFromChar(elemAttr.charAt(i)), ElementalEffectiveness.getByNumber(Integer.valueOf(String.valueOf(elemAttr.charAt(i + 1)))));
|
||||
}
|
||||
}
|
||||
|
||||
public static class BanishInfo {
|
||||
|
||||
private int map;
|
||||
private String portal, msg;
|
||||
|
||||
public BanishInfo(String msg, int map, String portal) {
|
||||
this.msg = msg;
|
||||
this.map = map;
|
||||
this.portal = portal;
|
||||
}
|
||||
|
||||
public int getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public String getPortal() {
|
||||
return portal;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
public static class loseItem {
|
||||
|
||||
private int id;
|
||||
private byte chance, x;
|
||||
|
||||
private loseItem(int id, byte chance, byte x) {
|
||||
this.id = id;
|
||||
this.chance = chance;
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public byte getX() {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public static class selfDestruction {
|
||||
|
||||
private byte action;
|
||||
private int removeAfter;
|
||||
private int hp;
|
||||
|
||||
private selfDestruction(byte action, int removeAfter, int hp) {
|
||||
this.action = action;
|
||||
this.removeAfter = removeAfter;
|
||||
this.hp = hp;
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public byte getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public int removeAfter() {
|
||||
return removeAfter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 life;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import life.MapleLifeFactory.BanishInfo;
|
||||
import life.MapleLifeFactory.loseItem;
|
||||
import life.MapleLifeFactory.selfDestruction;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
* @author Frz
|
||||
*/
|
||||
public class MapleMonsterStats {
|
||||
private boolean changeable;
|
||||
private int exp, hp, mp, level, PADamage, PDDamage, MADamage, MDDamage, dropPeriod, cp, buffToGive, removeAfter;
|
||||
private boolean boss, undead, ffaLoot, isExplosiveReward, firstAttack, removeOnMiss;
|
||||
private String name;
|
||||
private Map<String, Integer> animationTimes = new HashMap<String, Integer>();
|
||||
private Map<Element, ElementalEffectiveness> resistance = new HashMap<Element, ElementalEffectiveness>();
|
||||
private List<Integer> revives = Collections.emptyList();
|
||||
private byte tagColor, tagBgColor;
|
||||
private List<Pair<Integer, Integer>> skills = new ArrayList<Pair<Integer, Integer>>();
|
||||
private Pair<Integer, Integer> cool = null;
|
||||
private BanishInfo banish = null;
|
||||
private List<loseItem> loseItem = null;
|
||||
private selfDestruction selfDestruction = null;
|
||||
private boolean friendly;
|
||||
|
||||
public void setChange(boolean change) {
|
||||
this.changeable = change;
|
||||
}
|
||||
|
||||
public boolean isChangeable() {
|
||||
return changeable;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return exp;
|
||||
}
|
||||
|
||||
public void setExp(int exp) {
|
||||
this.exp = exp;
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public void setHp(int hp) {
|
||||
this.hp = hp;
|
||||
}
|
||||
|
||||
public int getMp() {
|
||||
return mp;
|
||||
}
|
||||
|
||||
public void setMp(int mp) {
|
||||
this.mp = mp;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int removeAfter() {
|
||||
return removeAfter;
|
||||
}
|
||||
|
||||
public void setRemoveAfter(int removeAfter) {
|
||||
this.removeAfter = removeAfter;
|
||||
}
|
||||
|
||||
public int getDropPeriod() {
|
||||
return dropPeriod;
|
||||
}
|
||||
|
||||
public void setDropPeriod(int dropPeriod) {
|
||||
this.dropPeriod = dropPeriod;
|
||||
}
|
||||
|
||||
public void setBoss(boolean boss) {
|
||||
this.boss = boss;
|
||||
}
|
||||
|
||||
public boolean isBoss() {
|
||||
return boss;
|
||||
}
|
||||
|
||||
public void setFfaLoot(boolean ffaLoot) {
|
||||
this.ffaLoot = ffaLoot;
|
||||
}
|
||||
|
||||
public boolean isFfaLoot() {
|
||||
return ffaLoot;
|
||||
}
|
||||
|
||||
public void setAnimationTime(String name, int delay) {
|
||||
animationTimes.put(name, delay);
|
||||
}
|
||||
|
||||
public int getAnimationTime(String name) {
|
||||
Integer ret = animationTimes.get(name);
|
||||
if (ret == null) {
|
||||
return 500;
|
||||
}
|
||||
return ret.intValue();
|
||||
}
|
||||
|
||||
public boolean isMobile() {
|
||||
return animationTimes.containsKey("move") || animationTimes.containsKey("fly");
|
||||
}
|
||||
|
||||
public List<Integer> getRevives() {
|
||||
return revives;
|
||||
}
|
||||
|
||||
public void setRevives(List<Integer> revives) {
|
||||
this.revives = revives;
|
||||
}
|
||||
|
||||
public void setUndead(boolean undead) {
|
||||
this.undead = undead;
|
||||
}
|
||||
|
||||
public boolean getUndead() {
|
||||
return undead;
|
||||
}
|
||||
|
||||
public void setEffectiveness(Element e, ElementalEffectiveness ee) {
|
||||
resistance.put(e, ee);
|
||||
}
|
||||
|
||||
public ElementalEffectiveness getEffectiveness(Element e) {
|
||||
ElementalEffectiveness elementalEffectiveness = resistance.get(e);
|
||||
if (elementalEffectiveness == null) {
|
||||
return ElementalEffectiveness.NORMAL;
|
||||
} else {
|
||||
return elementalEffectiveness;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public byte getTagColor() {
|
||||
return tagColor;
|
||||
}
|
||||
|
||||
public void setTagColor(int tagColor) {
|
||||
this.tagColor = (byte) tagColor;
|
||||
}
|
||||
|
||||
public byte getTagBgColor() {
|
||||
return tagBgColor;
|
||||
}
|
||||
|
||||
public void setTagBgColor(int tagBgColor) {
|
||||
this.tagBgColor = (byte) tagBgColor;
|
||||
}
|
||||
|
||||
public void setSkills(List<Pair<Integer, Integer>> skills) {
|
||||
for (Pair<Integer, Integer> skill : skills) {
|
||||
this.skills.add(skill);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Pair<Integer, Integer>> getSkills() {
|
||||
return Collections.unmodifiableList(this.skills);
|
||||
}
|
||||
|
||||
public int getNoSkills() {
|
||||
return this.skills.size();
|
||||
}
|
||||
|
||||
public boolean hasSkill(int skillId, int level) {
|
||||
for (Pair<Integer, Integer> skill : skills) {
|
||||
if (skill.getLeft() == skillId && skill.getRight() == level) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setFirstAttack(boolean firstAttack) {
|
||||
this.firstAttack = firstAttack;
|
||||
}
|
||||
|
||||
public boolean isFirstAttack() {
|
||||
return firstAttack;
|
||||
}
|
||||
|
||||
public void setBuffToGive(int buff) {
|
||||
this.buffToGive = buff;
|
||||
}
|
||||
|
||||
public int getBuffToGive() {
|
||||
return buffToGive;
|
||||
}
|
||||
|
||||
void removeEffectiveness(Element e) {
|
||||
resistance.remove(e);
|
||||
}
|
||||
|
||||
public BanishInfo getBanishInfo() {
|
||||
return banish;
|
||||
}
|
||||
|
||||
public void setBanishInfo(BanishInfo banish) {
|
||||
this.banish = banish;
|
||||
}
|
||||
|
||||
public int getPADamage() {
|
||||
return PADamage;
|
||||
}
|
||||
|
||||
public void setPADamage(int PADamage) {
|
||||
this.PADamage = PADamage;
|
||||
}
|
||||
|
||||
public int getCP() {
|
||||
return cp;
|
||||
}
|
||||
|
||||
public void setCP(int cp) {
|
||||
this.cp = cp;
|
||||
}
|
||||
|
||||
public List<loseItem> loseItem() {
|
||||
return loseItem;
|
||||
}
|
||||
|
||||
public void addLoseItem(loseItem li) {
|
||||
if (loseItem == null) {
|
||||
loseItem = new LinkedList<loseItem>();
|
||||
}
|
||||
loseItem.add(li);
|
||||
}
|
||||
|
||||
public selfDestruction selfDestruction() {
|
||||
return selfDestruction;
|
||||
}
|
||||
|
||||
public void setSelfDestruction(selfDestruction sd) {
|
||||
this.selfDestruction = sd;
|
||||
}
|
||||
|
||||
public void setExplosiveReward(boolean isExplosiveReward) {
|
||||
this.isExplosiveReward = isExplosiveReward;
|
||||
}
|
||||
|
||||
public boolean isExplosiveReward() {
|
||||
return isExplosiveReward;
|
||||
}
|
||||
|
||||
public void setRemoveOnMiss(boolean removeOnMiss) {
|
||||
this.removeOnMiss = removeOnMiss;
|
||||
}
|
||||
|
||||
public boolean removeOnMiss() {
|
||||
return removeOnMiss;
|
||||
}
|
||||
|
||||
public void setCool(Pair<Integer, Integer> cool) {
|
||||
this.cool = cool;
|
||||
}
|
||||
|
||||
public Pair<Integer, Integer> getCool() {
|
||||
return cool;
|
||||
}
|
||||
|
||||
public int getPDDamage() {
|
||||
return PDDamage;
|
||||
}
|
||||
|
||||
public int getMADamage() {
|
||||
return MADamage;
|
||||
}
|
||||
|
||||
public int getMDDamage() {
|
||||
return MDDamage;
|
||||
}
|
||||
|
||||
public boolean isFriendly() {
|
||||
return friendly;
|
||||
}
|
||||
|
||||
public void setFriendly(boolean value) {
|
||||
this.friendly = value;
|
||||
}
|
||||
|
||||
public void setPDDamage(int PDDamage) {
|
||||
this.PDDamage = PDDamage;
|
||||
}
|
||||
|
||||
public void setMADamage(int MADamage) {
|
||||
this.MADamage = MADamage;
|
||||
}
|
||||
|
||||
public void setMDDamage(int MDDamage) {
|
||||
this.MDDamage = MDDamage;
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
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 mapleskillbookchancefetcher;
|
||||
|
||||
import life.MapleLifeFactory;
|
||||
import life.MapleMonsterStats;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import tools.DatabaseConnection;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author RonanLana
|
||||
*
|
||||
* This application traces missing meso drop data on the underlying DB (that must be
|
||||
* defined on the DatabaseConnection file of this project) and generates a
|
||||
* SQL file that proposes missing drop entries for the drop_data table.
|
||||
*
|
||||
* The meso range is calculated accordingly with the target mob stats, such as level
|
||||
* and if it's a boss or not, similarly as how it has been done for the actual meso
|
||||
* drops.
|
||||
*
|
||||
*/
|
||||
public class MapleSkillbookChanceFetcher {
|
||||
|
||||
private static PrintWriter printWriter;
|
||||
private static String newFile = "lib/skillbook_drop_data.sql";
|
||||
|
||||
private static Map<Integer, MapleMonsterStats> mobStats;
|
||||
private static Map<Pair<Integer, Integer>, Integer> skillbookChances = new HashMap<>();
|
||||
|
||||
private static List<Entry<Pair<Integer, Integer>, Integer>> sortedSkillbookChances() {
|
||||
List<Entry<Pair<Integer, Integer>, Integer>> skillbookChancesList = new ArrayList<>(skillbookChances.entrySet());
|
||||
|
||||
Collections.sort(skillbookChancesList, new Comparator<Entry<Pair<Integer, Integer>, Integer>>() {
|
||||
@Override
|
||||
public int compare(Entry<Pair<Integer, Integer>, Integer> o1, Entry<Pair<Integer, Integer>, Integer> o2) {
|
||||
if (o1.getKey().getLeft().equals(o2.getKey().getLeft())) {
|
||||
return o1.getKey().getRight() < o2.getKey().getRight() ? -1 : (o1.getKey().getRight().equals(o2.getKey().getRight()) ? 0 : 1);
|
||||
}
|
||||
|
||||
return (o1.getKey().getLeft() < o2.getKey().getLeft()) ? -1 : 1;
|
||||
}
|
||||
});
|
||||
|
||||
return skillbookChancesList;
|
||||
}
|
||||
|
||||
private static boolean isLegendSkillUpgradeBook(int itemid) {
|
||||
int itemidBranch = itemid / 10000;
|
||||
return (itemidBranch == 228 && itemid >= 2280013 || itemidBranch == 229 && itemid >= 2290126); // drop rate of Legends are higher
|
||||
}
|
||||
|
||||
private static void fetchSkillbookDropChances() {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
|
||||
try {
|
||||
PreparedStatement ps = con.prepareStatement("SELECT dropperid, itemid FROM drop_data WHERE itemid >= 2280000 AND itemid < 2300000");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
while(rs.next()) {
|
||||
int mobid = rs.getInt("dropperid");
|
||||
int itemid = rs.getInt("itemid");
|
||||
|
||||
int expectedChance = 1000;
|
||||
|
||||
if (mobStats.get(mobid) != null) {
|
||||
int level = mobStats.get(mobid).getLevel();
|
||||
expectedChance *= Math.max(2, (level - 80) / 15);
|
||||
|
||||
if (mobStats.get(mobid).isBoss()) {
|
||||
expectedChance *= 20;
|
||||
} else {
|
||||
expectedChance *= 1;
|
||||
}
|
||||
} else {
|
||||
expectedChance = 1287;
|
||||
}
|
||||
|
||||
if (isLegendSkillUpgradeBook(itemid)) { // drop rate of Legends seems to be higher than explorers, in retrospect from values in DB
|
||||
expectedChance *= 3;
|
||||
}
|
||||
|
||||
skillbookChances.put(new Pair<>(mobid, itemid), expectedChance);
|
||||
}
|
||||
|
||||
rs.close();
|
||||
ps.close();
|
||||
con.close();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void printSkillbookChanceUpdateSqlHeader() {
|
||||
printWriter.println(" # SQL File autogenerated from the MapleSkillbookChanceFetcher feature by Ronan Lana.");
|
||||
printWriter.println(" # Generated data takes into account mob stats such as level and boss for the chance rates.");
|
||||
printWriter.println();
|
||||
|
||||
printWriter.println(" REPLACE INTO drop_data (`dropperid`, `itemid`, `minimum_quantity`, `maximum_quantity`, `questid`, `chance`) VALUES");
|
||||
}
|
||||
|
||||
private static void generateSkillbookChanceUpdateFile() {
|
||||
try {
|
||||
printWriter = new PrintWriter(newFile, "UTF-8");
|
||||
|
||||
printSkillbookChanceUpdateSqlHeader();
|
||||
|
||||
List<Entry<Pair<Integer, Integer>, Integer>> skillbookChancesList = sortedSkillbookChances();
|
||||
for (Entry<Pair<Integer, Integer>, Integer> e : skillbookChancesList) {
|
||||
printWriter.println("(" + e.getKey().getLeft() + ", " + e.getKey().getRight() + ", 1, 1, 0, " + e.getValue() + "),");
|
||||
}
|
||||
|
||||
printWriter.close();
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// load mob stats from WZ
|
||||
mobStats = MapleLifeFactory.getAllMonsterStats();
|
||||
|
||||
fetchSkillbookDropChances();
|
||||
generateSkillbookChanceUpdateFile();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public interface MapleCanvas {
|
||||
int getHeight();
|
||||
int getWidth();
|
||||
BufferedImage getImage();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
import java.util.List;
|
||||
import provider.wz.MapleDataType;
|
||||
|
||||
public interface MapleData extends MapleDataEntity, Iterable<MapleData> {
|
||||
@Override
|
||||
public String getName();
|
||||
public MapleDataType getType();
|
||||
public List<MapleData> getChildren();
|
||||
public MapleData getChildByPath(String path);
|
||||
public Object getData();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public interface MapleDataDirectoryEntry extends MapleDataEntry {
|
||||
public List<MapleDataDirectoryEntry> getSubdirectories();
|
||||
public List<MapleDataFileEntry> getFiles();
|
||||
public MapleDataEntry getEntry(String name);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public interface MapleDataEntity {
|
||||
public String getName();
|
||||
public MapleDataEntity getParent();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public interface MapleDataEntry extends MapleDataEntity {
|
||||
public String getName();
|
||||
public int getSize();
|
||||
public int getChecksum();
|
||||
public int getOffset();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
*/
|
||||
public interface MapleDataFileEntry extends MapleDataEntry {
|
||||
public void setOffset(int offset);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
public interface MapleDataProvider {
|
||||
MapleData getData(String path);
|
||||
MapleDataDirectoryEntry getRoot();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import provider.wz.WZFile;
|
||||
import provider.wz.XMLWZFile;
|
||||
|
||||
public class MapleDataProviderFactory {
|
||||
private final static String wzPath = System.getProperty("wzpath");
|
||||
|
||||
private static MapleDataProvider getWZ(File in, boolean provideImages) {
|
||||
if (in.getName().toLowerCase().endsWith("wz") && !in.isDirectory()) {
|
||||
try {
|
||||
return new WZFile(in, provideImages);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Loading WZ File failed", e);
|
||||
}
|
||||
} else {
|
||||
return new XMLWZFile(in);
|
||||
}
|
||||
}
|
||||
|
||||
public static MapleDataProvider getDataProvider(File in) {
|
||||
return getWZ(in, false);
|
||||
}
|
||||
|
||||
public static MapleDataProvider getImageProvidingDataProvider(File in) {
|
||||
return getWZ(in, true);
|
||||
}
|
||||
|
||||
public static File fileInWZPath(String filename) {
|
||||
return new File(wzPath, filename);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
import provider.wz.MapleDataType;
|
||||
|
||||
public class MapleDataTool {
|
||||
public static String getString(MapleData data) {
|
||||
return ((String) data.getData());
|
||||
}
|
||||
|
||||
public static String getString(MapleData data, String def) {
|
||||
if (data == null || data.getData() == null) {
|
||||
return def;
|
||||
} else {
|
||||
return ((String) data.getData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(String path, MapleData data) {
|
||||
return getString(data.getChildByPath(path));
|
||||
}
|
||||
|
||||
public static String getString(String path, MapleData data, String def) {
|
||||
return getString(data.getChildByPath(path), def);
|
||||
}
|
||||
|
||||
public static double getDouble(MapleData data) {
|
||||
return ((Double) data.getData()).doubleValue();
|
||||
}
|
||||
|
||||
public static float getFloat(MapleData data) {
|
||||
return ((Float) data.getData()).floatValue();
|
||||
}
|
||||
|
||||
public static int getInt(MapleData data) {
|
||||
if (data == null || data.getData() == null) {
|
||||
return 0;// DEF?
|
||||
}
|
||||
return ((Integer) data.getData()).intValue();
|
||||
}
|
||||
|
||||
public static int getInt(String path, MapleData data) {
|
||||
return getInt(data.getChildByPath(path));
|
||||
}
|
||||
|
||||
public static int getIntConvert(MapleData data) {
|
||||
if (data.getType() == MapleDataType.STRING) {
|
||||
return Integer.parseInt(getString(data));
|
||||
} else {
|
||||
return getInt(data);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getIntConvert(String path, MapleData data) {
|
||||
MapleData d = data.getChildByPath(path);
|
||||
if (d.getType() == MapleDataType.STRING) {
|
||||
return Integer.parseInt(getString(d));
|
||||
} else {
|
||||
return getInt(d);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(MapleData data, int def) {
|
||||
if (data == null || data.getData() == null) {
|
||||
return def;
|
||||
} else if (data.getType() == MapleDataType.STRING) {
|
||||
return Integer.parseInt(getString(data));
|
||||
} else {
|
||||
return ((Integer) data.getData()).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getInt(String path, MapleData data, int def) {
|
||||
return getInt(data.getChildByPath(path), def);
|
||||
}
|
||||
|
||||
public static int getIntConvert(String path, MapleData data, int def) {
|
||||
MapleData d = data.getChildByPath(path);
|
||||
if (d == null) {
|
||||
return def;
|
||||
}
|
||||
if (d.getType() == MapleDataType.STRING) {
|
||||
try {
|
||||
return Integer.parseInt(getString(d));
|
||||
} catch (NumberFormatException nfe) {
|
||||
nfe.printStackTrace();
|
||||
return def;
|
||||
}
|
||||
} else {
|
||||
return getInt(d, def);
|
||||
}
|
||||
}
|
||||
|
||||
public static BufferedImage getImage(MapleData data) {
|
||||
return ((MapleCanvas) data.getData()).getImage();
|
||||
}
|
||||
|
||||
public static Point getPoint(MapleData data) {
|
||||
return ((Point) data.getData());
|
||||
}
|
||||
|
||||
public static Point getPoint(String path, MapleData data) {
|
||||
return getPoint(data.getChildByPath(path));
|
||||
}
|
||||
|
||||
public static Point getPoint(String path, MapleData data, Point def) {
|
||||
final MapleData pointData = data.getChildByPath(path);
|
||||
if (pointData == null) {
|
||||
return def;
|
||||
}
|
||||
return getPoint(pointData);
|
||||
}
|
||||
|
||||
public static String getFullDataPath(MapleData data) {
|
||||
String path = "";
|
||||
MapleDataEntity myData = data;
|
||||
while (myData != null) {
|
||||
path = myData.getName() + "/" + path;
|
||||
myData = myData.getParent();
|
||||
}
|
||||
return path.substring(0, path.length() - 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import provider.MapleCanvas;
|
||||
|
||||
public class FileStoredPngMapleCanvas implements MapleCanvas {
|
||||
private File file;
|
||||
private int width;
|
||||
private int height;
|
||||
private BufferedImage image;
|
||||
|
||||
public FileStoredPngMapleCanvas(int width, int height, File fileIn) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.file = fileIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage getImage() {
|
||||
loadImageIfNecessary();
|
||||
return image;
|
||||
}
|
||||
|
||||
private void loadImageIfNecessary() {
|
||||
if (image == null) {
|
||||
try {
|
||||
image = ImageIO.read(file);
|
||||
// replace the dimensions loaded from the wz by the REAL dimensions from the image - should be equal tho
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
public class ImgMapleSound {
|
||||
private int dataLength, offset;
|
||||
|
||||
public ImgMapleSound(int dataLength, int offset) {
|
||||
this.dataLength = dataLength;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getDataLength() {
|
||||
return dataLength;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import tools.data.input.GenericLittleEndianAccessor;
|
||||
import tools.data.input.InputStreamByteStream;
|
||||
import tools.data.input.LittleEndianAccessor;
|
||||
|
||||
public class ListWZFile {
|
||||
private LittleEndianAccessor lea;
|
||||
private List<String> entries = new ArrayList<String>();
|
||||
private static Collection<String> modernImgs = new HashSet<String>();
|
||||
|
||||
public static byte[] xorBytes(byte[] a, byte[] b) {
|
||||
byte[] wusched = new byte[a.length];
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
wusched[i] = (byte) (a[i] ^ b[i]);
|
||||
}
|
||||
return wusched;
|
||||
}
|
||||
|
||||
public ListWZFile(File listwz) throws FileNotFoundException {
|
||||
lea = new GenericLittleEndianAccessor(new InputStreamByteStream(new BufferedInputStream(new FileInputStream(listwz))));
|
||||
while (lea.available() > 0) {
|
||||
int l = lea.readInt() * 2;
|
||||
byte[] chunk = new byte[l];
|
||||
for (int i = 0; i < chunk.length; i++) {
|
||||
chunk[i] = lea.readByte();
|
||||
}
|
||||
lea.readChar();
|
||||
final String value = String.valueOf(WZTool.readListString(chunk));
|
||||
entries.add(value);
|
||||
}
|
||||
entries = Collections.unmodifiableList(entries);
|
||||
}
|
||||
|
||||
public List<String> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
final String listWz = System.getProperty("listwz");
|
||||
if (listWz != null) {
|
||||
ListWZFile listwz;
|
||||
try {
|
||||
listwz = new ListWZFile(MapleDataProviderFactory.fileInWZPath("List.wz"));
|
||||
modernImgs = new HashSet<String>(listwz.getEntries());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isModernImgFile(String path) {
|
||||
return modernImgs.contains(path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
public enum MapleDataType {
|
||||
NONE, IMG_0x00, SHORT, INT, FLOAT, DOUBLE, STRING, EXTENDED, PROPERTY, CANVAS, VECTOR, CONVEX, SOUND, UOL, UNKNOWN_TYPE, UNKNOWN_EXTENDED_TYPE;
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.PixelInterleavedSampleModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Inflater;
|
||||
import provider.MapleCanvas;
|
||||
|
||||
public class PNGMapleCanvas implements MapleCanvas {
|
||||
private static final int[] ZAHLEN = new int[]{2, 1, 0, 3};
|
||||
private int height;
|
||||
private int width;
|
||||
private int dataLength;
|
||||
private int format;
|
||||
private byte[] data;
|
||||
|
||||
public PNGMapleCanvas(int width, int height, int dataLength, int format, byte[] data) {
|
||||
super();
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.dataLength = dataLength;
|
||||
this.format = format;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
private byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage getImage() {
|
||||
int sizeUncompressed = 0;
|
||||
int size8888 = 0;
|
||||
int maxWriteBuf = 2;
|
||||
int maxHeight = 3;
|
||||
byte[] writeBuf = new byte[maxWriteBuf];
|
||||
@SuppressWarnings ("unused")
|
||||
byte[] rowPointers = new byte[maxHeight];
|
||||
switch (getFormat()) {
|
||||
case 1:
|
||||
case 513:
|
||||
sizeUncompressed = getHeight() * getWidth() * 4;
|
||||
break;
|
||||
case 2:
|
||||
sizeUncompressed = getHeight() * getWidth() * 8;
|
||||
break;
|
||||
case 517:
|
||||
sizeUncompressed = getHeight() * getWidth() / 128;
|
||||
break;
|
||||
}
|
||||
size8888 = getHeight() * getWidth() * 8;
|
||||
if (size8888 > maxWriteBuf) {
|
||||
maxWriteBuf = size8888;
|
||||
writeBuf = new byte[maxWriteBuf];
|
||||
}
|
||||
if (getHeight() > maxHeight) {
|
||||
maxHeight = getHeight();
|
||||
rowPointers = new byte[maxHeight];
|
||||
}
|
||||
Inflater dec = new Inflater();
|
||||
dec.setInput(getData(), 0, dataLength);
|
||||
int declen = 0;
|
||||
byte[] uc = new byte[sizeUncompressed];
|
||||
try {
|
||||
declen = dec.inflate(uc);
|
||||
} catch (DataFormatException ex) {
|
||||
throw new RuntimeException("zlib fucks", ex);
|
||||
}
|
||||
dec.end();
|
||||
if (getFormat() == 1) {
|
||||
for (int i = 0; i < sizeUncompressed; i++) {
|
||||
byte low = (byte) (uc[i] & 0x0F);
|
||||
byte high = (byte) (uc[i] & 0xF0);
|
||||
writeBuf[(i << 1)] = (byte) (((low << 4) | low) & 0xFF);
|
||||
writeBuf[(i << 1) + 1] = (byte) (high | ((high >>> 4) & 0xF));
|
||||
}
|
||||
} else if (getFormat() == 2) {
|
||||
writeBuf = uc;
|
||||
} else if (getFormat() == 513) {
|
||||
for (int i = 0; i < declen; i += 2) {
|
||||
byte bBits = (byte) ((uc[i] & 0x1F) << 3);
|
||||
byte gBits = (byte) (((uc[i + 1] & 0x07) << 5) | ((uc[i] & 0xE0) >> 3));
|
||||
byte rBits = (byte) (uc[i + 1] & 0xF8);
|
||||
writeBuf[(i << 1)] = (byte) (bBits | (bBits >> 5));
|
||||
writeBuf[(i << 1) + 1] = (byte) (gBits | (gBits >> 6));
|
||||
writeBuf[(i << 1) + 2] = (byte) (rBits | (rBits >> 5));
|
||||
writeBuf[(i << 1) + 3] = (byte) 0xFF;
|
||||
}
|
||||
} else if (getFormat() == 517) {
|
||||
byte b = 0x00;
|
||||
int pixelIndex = 0;
|
||||
for (int i = 0; i < declen; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
b = (byte) (((uc[i] & (0x01 << (7 - j))) >> (7 - j)) * 255);
|
||||
for (int k = 0; k < 16; k++) {
|
||||
pixelIndex = (i << 9) + (j << 6) + k * 2;
|
||||
writeBuf[pixelIndex] = b;
|
||||
writeBuf[pixelIndex + 1] = b;
|
||||
writeBuf[pixelIndex + 2] = b;
|
||||
writeBuf[pixelIndex + 3] = (byte) 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DataBufferByte imgData = new DataBufferByte(writeBuf, sizeUncompressed);
|
||||
SampleModel sm = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, getWidth(), getHeight(), 4, getWidth() * 4, ZAHLEN);
|
||||
WritableRaster imgRaster = Raster.createWritableRaster(sm, imgData, new Point(0, 0));
|
||||
BufferedImage aa = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
aa.setData(imgRaster);
|
||||
return aa;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import provider.MapleDataDirectoryEntry;
|
||||
import provider.MapleDataEntity;
|
||||
import provider.MapleDataEntry;
|
||||
import provider.MapleDataFileEntry;
|
||||
|
||||
public class WZDirectoryEntry extends WZEntry implements MapleDataDirectoryEntry {
|
||||
private List<MapleDataDirectoryEntry> subdirs = new ArrayList<MapleDataDirectoryEntry>();
|
||||
private List<MapleDataFileEntry> files = new ArrayList<MapleDataFileEntry>();
|
||||
private Map<String, MapleDataEntry> entries = new HashMap<String, MapleDataEntry>();
|
||||
|
||||
public WZDirectoryEntry(String name, int size, int checksum, MapleDataEntity parent) {
|
||||
super(name, size, checksum, parent);
|
||||
}
|
||||
|
||||
public WZDirectoryEntry() {
|
||||
super(null, 0, 0, null);
|
||||
}
|
||||
|
||||
public void addDirectory(MapleDataDirectoryEntry dir) {
|
||||
subdirs.add(dir);
|
||||
entries.put(dir.getName(), dir);
|
||||
}
|
||||
|
||||
public void addFile(MapleDataFileEntry fileEntry) {
|
||||
files.add(fileEntry);
|
||||
entries.put(fileEntry.getName(), fileEntry);
|
||||
}
|
||||
|
||||
public List<MapleDataDirectoryEntry> getSubdirectories() {
|
||||
return Collections.unmodifiableList(subdirs);
|
||||
}
|
||||
|
||||
public List<MapleDataFileEntry> getFiles() {
|
||||
return Collections.unmodifiableList(files);
|
||||
}
|
||||
|
||||
public MapleDataEntry getEntry(String name) {
|
||||
return entries.get(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import provider.MapleDataEntity;
|
||||
import provider.MapleDataEntry;
|
||||
|
||||
public class WZEntry implements MapleDataEntry {
|
||||
private String name;
|
||||
private int size;
|
||||
private int checksum;
|
||||
private int offset;
|
||||
private MapleDataEntity parent;
|
||||
|
||||
public WZEntry(String name, int size, int checksum, MapleDataEntity parent) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.size = size;
|
||||
this.checksum = checksum;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getChecksum() {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public MapleDataEntity getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataDirectoryEntry;
|
||||
import provider.MapleDataFileEntry;
|
||||
import provider.MapleDataProvider;
|
||||
import tools.data.input.GenericLittleEndianAccessor;
|
||||
import tools.data.input.GenericSeekableLittleEndianAccessor;
|
||||
import tools.data.input.InputStreamByteStream;
|
||||
import tools.data.input.LittleEndianAccessor;
|
||||
import tools.data.input.RandomAccessByteStream;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public class WZFile implements MapleDataProvider {
|
||||
static {
|
||||
ListWZFile.init();
|
||||
}
|
||||
private File wzfile;
|
||||
private LittleEndianAccessor lea;
|
||||
private SeekableLittleEndianAccessor slea;
|
||||
private int headerSize;
|
||||
private WZDirectoryEntry root;
|
||||
private boolean provideImages;
|
||||
private int cOffset;
|
||||
|
||||
public WZFile(File wzfile, boolean provideImages) throws IOException {
|
||||
this.wzfile = wzfile;
|
||||
lea = new GenericLittleEndianAccessor(new InputStreamByteStream(new BufferedInputStream(new FileInputStream(wzfile))));
|
||||
RandomAccessFile raf = new RandomAccessFile(wzfile, "r");
|
||||
slea = new GenericSeekableLittleEndianAccessor(new RandomAccessByteStream(raf));
|
||||
root = new WZDirectoryEntry(wzfile.getName(), 0, 0, null);
|
||||
this.provideImages = provideImages;
|
||||
load();
|
||||
}
|
||||
|
||||
private void load() throws IOException {
|
||||
lea.readAsciiString(4);
|
||||
lea.readInt();
|
||||
lea.readInt();
|
||||
headerSize = lea.readInt();
|
||||
lea.readNullTerminatedAsciiString();
|
||||
lea.readShort();
|
||||
parseDirectory(root);
|
||||
cOffset = (int) lea.getBytesRead();
|
||||
getOffsets(root);
|
||||
}
|
||||
|
||||
private void getOffsets(MapleDataDirectoryEntry dir) {
|
||||
for (MapleDataFileEntry file : dir.getFiles()) {
|
||||
file.setOffset(cOffset);
|
||||
cOffset += file.getSize();
|
||||
}
|
||||
for (MapleDataDirectoryEntry sdir : dir.getSubdirectories()) {
|
||||
getOffsets(sdir);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDirectory(WZDirectoryEntry dir) {
|
||||
int entries = WZTool.readValue(lea);
|
||||
for (int i = 0; i < entries; i++) {
|
||||
byte marker = lea.readByte();
|
||||
String name = null;
|
||||
int size, checksum;
|
||||
switch (marker) {
|
||||
case 0x02:
|
||||
name = WZTool.readDecodedStringAtOffsetAndReset(slea, lea.readInt() + this.headerSize + 1);
|
||||
size = WZTool.readValue(lea);
|
||||
checksum = WZTool.readValue(lea);
|
||||
lea.readInt(); //dummy int
|
||||
dir.addFile(new WZFileEntry(name, size, checksum, dir));
|
||||
break;
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
name = WZTool.readDecodedString(lea);
|
||||
size = WZTool.readValue(lea);
|
||||
checksum = WZTool.readValue(lea);
|
||||
lea.readInt(); //dummy int
|
||||
if (marker == 3) {
|
||||
dir.addDirectory(new WZDirectoryEntry(name, size, checksum, dir));
|
||||
} else {
|
||||
dir.addFile(new WZFileEntry(name, size, checksum, dir));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
for (MapleDataDirectoryEntry idir : dir.getSubdirectories()) {
|
||||
parseDirectory((WZDirectoryEntry) idir);
|
||||
}
|
||||
}
|
||||
|
||||
public WZIMGFile getImgFile(String path) throws IOException {
|
||||
String segments[] = path.split("/");
|
||||
WZDirectoryEntry dir = root;
|
||||
for (int x = 0; x < segments.length - 1; x++) {
|
||||
dir = (WZDirectoryEntry) dir.getEntry(segments[x]);
|
||||
if (dir == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
WZFileEntry entry = (WZFileEntry) dir.getEntry(segments[segments.length - 1]);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
String fullPath = wzfile.getName().substring(0, wzfile.getName().length() - 3).toLowerCase() + "/" + path;
|
||||
return new WZIMGFile(this.wzfile, entry, provideImages, ListWZFile.isModernImgFile(fullPath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized MapleData getData(String path) {
|
||||
try {
|
||||
WZIMGFile imgFile = getImgFile(path);
|
||||
if (imgFile == null) {
|
||||
return null;
|
||||
}
|
||||
MapleData ret = imgFile.getRoot();
|
||||
return ret;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleDataDirectoryEntry getRoot() {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import provider.MapleDataEntity;
|
||||
import provider.MapleDataFileEntry;
|
||||
|
||||
public class WZFileEntry extends WZEntry implements MapleDataFileEntry {
|
||||
private int offset;
|
||||
|
||||
public WZFileEntry(String name, int size, int checksum, MapleDataEntity parent) {
|
||||
super(name, size, checksum, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataEntity;
|
||||
|
||||
public class WZIMGEntry implements MapleData {
|
||||
private String name;
|
||||
private MapleDataType type;
|
||||
private List<MapleData> children = new ArrayList<MapleData>(10);
|
||||
private Object data;
|
||||
private MapleDataEntity parent;
|
||||
|
||||
public WZIMGEntry(MapleDataEntity parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleDataType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MapleData> getChildren() {
|
||||
return Collections.unmodifiableList(children);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleData getChildByPath(String path) {
|
||||
String segments[] = path.split("/");
|
||||
if (segments[0].equals("..")) {
|
||||
return ((MapleData) getParent()).getChildByPath(path.substring(path.indexOf("/") + 1));
|
||||
}
|
||||
MapleData ret = this;
|
||||
for (int x = 0; x < segments.length; x++) {
|
||||
boolean foundChild = false;
|
||||
for (MapleData child : ret.getChildren()) {
|
||||
if (child.getName().equals(segments[x])) {
|
||||
ret = child;
|
||||
foundChild = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundChild) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setType(MapleDataType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setData(Object data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void addChild(WZIMGEntry entry) {
|
||||
children.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<MapleData> iterator() {
|
||||
return getChildren().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + ":" + getData();
|
||||
}
|
||||
|
||||
public MapleDataEntity getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
((ArrayList<MapleData>) children).trimToSize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import tools.data.input.GenericSeekableLittleEndianAccessor;
|
||||
import tools.data.input.RandomAccessByteStream;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public class WZIMGFile {
|
||||
private WZFileEntry file;
|
||||
private WZIMGEntry root;
|
||||
private boolean provideImages;
|
||||
@SuppressWarnings ("unused")
|
||||
private boolean modernImg;
|
||||
|
||||
public WZIMGFile(File wzfile, WZFileEntry file, boolean provideImages, boolean modernImg) throws IOException {
|
||||
RandomAccessFile raf = new RandomAccessFile(wzfile, "r");
|
||||
SeekableLittleEndianAccessor slea = new GenericSeekableLittleEndianAccessor(new RandomAccessByteStream(raf));
|
||||
slea.seek(file.getOffset());
|
||||
this.file = file;
|
||||
this.provideImages = provideImages;
|
||||
root = new WZIMGEntry(file.getParent());
|
||||
root.setName(file.getName());
|
||||
root.setType(MapleDataType.EXTENDED);
|
||||
this.modernImg = modernImg;
|
||||
parseExtended(root, slea, 0);
|
||||
root.finish();
|
||||
raf.close();
|
||||
}
|
||||
|
||||
protected void dumpImg(OutputStream out, SeekableLittleEndianAccessor slea) throws IOException {
|
||||
DataOutputStream os = new DataOutputStream(out);
|
||||
long oldPos = slea.getPosition();
|
||||
slea.seek(file.getOffset());
|
||||
for (int x = 0; x < file.getSize(); x++) {
|
||||
os.write(slea.readByte());
|
||||
}
|
||||
slea.seek(oldPos);
|
||||
}
|
||||
|
||||
public WZIMGEntry getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
private void parse(WZIMGEntry entry, SeekableLittleEndianAccessor slea) {
|
||||
byte marker = slea.readByte();
|
||||
switch (marker) {
|
||||
case 0: {
|
||||
String name = WZTool.readDecodedString(slea);
|
||||
entry.setName(name);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
String name = WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt());
|
||||
entry.setName(name);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
System.out.println("Unknown Image identifier: " + marker + " at offset " + (slea.getPosition() - file.getOffset()));
|
||||
}
|
||||
marker = slea.readByte();
|
||||
switch (marker) {
|
||||
case 0:
|
||||
entry.setType(MapleDataType.IMG_0x00);
|
||||
break;
|
||||
case 2:
|
||||
case 11: //??? no idea, since 0.49
|
||||
entry.setType(MapleDataType.SHORT);
|
||||
entry.setData(Short.valueOf(slea.readShort()));
|
||||
break;
|
||||
case 3:
|
||||
entry.setType(MapleDataType.INT);
|
||||
entry.setData(Integer.valueOf(WZTool.readValue(slea)));
|
||||
break;
|
||||
case 4:
|
||||
entry.setType(MapleDataType.FLOAT);
|
||||
entry.setData(Float.valueOf(WZTool.readFloatValue(slea)));
|
||||
break;
|
||||
case 5:
|
||||
entry.setType(MapleDataType.DOUBLE);
|
||||
entry.setData(Double.valueOf(slea.readDouble()));
|
||||
break;
|
||||
case 8:
|
||||
entry.setType(MapleDataType.STRING);
|
||||
byte iMarker = slea.readByte();
|
||||
if (iMarker == 0) {
|
||||
entry.setData(WZTool.readDecodedString(slea));
|
||||
} else if (iMarker == 1) {
|
||||
entry.setData(WZTool.readDecodedStringAtOffsetAndReset(slea, slea.readInt() + file.getOffset()));
|
||||
} else {
|
||||
System.out.println("Unknown String type " + iMarker);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
entry.setType(MapleDataType.EXTENDED);
|
||||
long endOfExtendedBlock = slea.readInt();
|
||||
endOfExtendedBlock += slea.getPosition();
|
||||
parseExtended(entry, slea, endOfExtendedBlock);
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unknown Image type " + marker);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseExtended(WZIMGEntry entry, SeekableLittleEndianAccessor slea, long endOfExtendedBlock) {
|
||||
byte marker = slea.readByte();
|
||||
String type;
|
||||
switch (marker) {
|
||||
case 0x73:
|
||||
type = WZTool.readDecodedString(slea);
|
||||
break;
|
||||
case 0x1B:
|
||||
type = WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt());
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown extended image identifier: " + marker + " at offset " +
|
||||
(slea.getPosition() - file.getOffset()));
|
||||
}
|
||||
if (type.equals("Property")) {
|
||||
entry.setType(MapleDataType.PROPERTY);
|
||||
slea.readByte();
|
||||
slea.readByte();
|
||||
int children = WZTool.readValue(slea);
|
||||
for (int i = 0; i < children; i++) {
|
||||
WZIMGEntry cEntry = new WZIMGEntry(entry);
|
||||
parse(cEntry, slea);
|
||||
cEntry.finish();
|
||||
entry.addChild(cEntry);
|
||||
}
|
||||
} else if (type.equals("Canvas")) {
|
||||
entry.setType(MapleDataType.CANVAS);
|
||||
slea.readByte();
|
||||
marker = slea.readByte();
|
||||
if (marker == 0) {
|
||||
// do nothing
|
||||
} else if (marker == 1) {
|
||||
slea.readByte();
|
||||
slea.readByte();
|
||||
int children = WZTool.readValue(slea);
|
||||
for (int i = 0; i < children; i++) {
|
||||
WZIMGEntry child = new WZIMGEntry(entry);
|
||||
parse(child, slea);
|
||||
child.finish();
|
||||
entry.addChild(child);
|
||||
}
|
||||
} else {
|
||||
System.out.println("Canvas marker != 1 (" + marker + ")");
|
||||
}
|
||||
int width = WZTool.readValue(slea);
|
||||
int height = WZTool.readValue(slea);
|
||||
int format = WZTool.readValue(slea);
|
||||
int format2 = slea.readByte();
|
||||
slea.readInt();
|
||||
int dataLength = slea.readInt() - 1;
|
||||
slea.readByte();
|
||||
if (provideImages) {
|
||||
byte[] pngdata = slea.read(dataLength);
|
||||
entry.setData(new PNGMapleCanvas(width, height, dataLength, format + format2, pngdata));
|
||||
} else {
|
||||
entry.setData(new PNGMapleCanvas(width, height, dataLength, format + format2, null));
|
||||
slea.skip(dataLength);
|
||||
}
|
||||
} else if (type.equals("Shape2D#Vector2D")) {
|
||||
entry.setType(MapleDataType.VECTOR);
|
||||
int x = WZTool.readValue(slea);
|
||||
int y = WZTool.readValue(slea);
|
||||
entry.setData(new Point(x, y));
|
||||
} else if (type.equals("Shape2D#Convex2D")) {
|
||||
int children = WZTool.readValue(slea);
|
||||
for (int i = 0; i < children; i++) {
|
||||
WZIMGEntry cEntry = new WZIMGEntry(entry);
|
||||
parseExtended(cEntry, slea, 0);
|
||||
cEntry.finish();
|
||||
entry.addChild(cEntry);
|
||||
}
|
||||
} else if (type.equals("Sound_DX8")) {
|
||||
entry.setType(MapleDataType.SOUND);
|
||||
slea.readByte();
|
||||
int dataLength = WZTool.readValue(slea);
|
||||
WZTool.readValue(slea); // no clue what this is
|
||||
int offset = (int) slea.getPosition();
|
||||
entry.setData(new ImgMapleSound(dataLength, offset - file.getOffset()));
|
||||
slea.seek(endOfExtendedBlock);
|
||||
} else if (type.equals("UOL")) {
|
||||
entry.setType(MapleDataType.UOL);
|
||||
slea.readByte();
|
||||
byte uolmarker = slea.readByte();
|
||||
switch (uolmarker) {
|
||||
case 0:
|
||||
entry.setData(WZTool.readDecodedString(slea));
|
||||
break;
|
||||
case 1:
|
||||
entry.setData(WZTool.readDecodedStringAtOffsetAndReset(slea, file.getOffset() + slea.readInt()));
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unknown UOL marker: " + uolmarker + " " + entry.getName());
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled extended type: " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import tools.data.input.LittleEndianAccessor;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/*
|
||||
* Ported Code, see WZFile.java for more info
|
||||
*/
|
||||
public class WZTool {
|
||||
private static byte[] encKey;
|
||||
|
||||
static {
|
||||
byte[] iv = new byte[]{(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,
|
||||
(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,
|
||||
(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,
|
||||
(byte) 0x4d, (byte) 0x23, (byte) 0xc7, (byte) 0x2b,};
|
||||
byte[] key = new byte[]{(byte) 0x13, 0x00, 0x00, 0x00,
|
||||
(byte) 0x08, 0x00, 0x00, 0x00,
|
||||
(byte) 0x06, 0x00, 0x00, 0x00,
|
||||
(byte) 0xB4, 0x00, 0x00, 0x00,
|
||||
(byte) 0x1B, 0x00, 0x00, 0x00,
|
||||
(byte) 0x0F, 0x00, 0x00, 0x00,
|
||||
(byte) 0x33, 0x00, 0x00, 0x00,
|
||||
(byte) 0x52, 0x00, 0x00, 0x00
|
||||
};
|
||||
Cipher cipher = null;
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
|
||||
try {
|
||||
cipher = Cipher.getInstance("AES");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
encKey = new byte[0xFFFF];
|
||||
for (int i = 0; i < (0xFFFF / 16); i++) {
|
||||
try {
|
||||
iv = cipher.doFinal(iv);
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.arraycopy(iv, 0, encKey, (i * 16), 16);
|
||||
}
|
||||
try {
|
||||
iv = cipher.doFinal(iv);
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
} catch (BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.arraycopy(iv, 0, encKey, 65520, 15);
|
||||
}
|
||||
|
||||
public static byte[] readListString(byte[] str) {
|
||||
for (int i = 0; i < str.length; i++) {
|
||||
str[i] = (byte) (str[i] ^ encKey[i]);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String readDecodedString(LittleEndianAccessor llea) {
|
||||
int strLength;
|
||||
byte b = llea.readByte();
|
||||
if (b == 0x00) {
|
||||
return "";
|
||||
}
|
||||
if (b >= 0) {
|
||||
if (b == 0x7F) {
|
||||
strLength = llea.readInt();
|
||||
} else {
|
||||
strLength = (int) b;
|
||||
}
|
||||
if (strLength < 0) {
|
||||
return "";
|
||||
}
|
||||
byte str[] = new byte[strLength * 2];
|
||||
for (int i = 0; i < strLength * 2; i++) {
|
||||
str[i] = llea.readByte();
|
||||
}
|
||||
return DecryptUnicodeStr(str);
|
||||
} else {
|
||||
if (b == -128) {
|
||||
strLength = llea.readInt();
|
||||
} else {
|
||||
strLength = -b;
|
||||
}
|
||||
if (strLength < 0) {
|
||||
return "";
|
||||
}
|
||||
byte str[] = new byte[strLength];
|
||||
for (int i = 0; i < strLength; i++) {
|
||||
str[i] = llea.readByte();
|
||||
}
|
||||
return DecryptAsciiStr(str);
|
||||
}
|
||||
}
|
||||
|
||||
public static String DecryptAsciiStr(byte[] str) {
|
||||
byte xorByte = (byte) 0xAA;
|
||||
for (int i = 0; i < str.length; i++) {
|
||||
str[i] = (byte) (str[i] ^ xorByte ^ encKey[i]);
|
||||
xorByte++;
|
||||
}
|
||||
return new String(str);
|
||||
}
|
||||
|
||||
public static String DecryptUnicodeStr(byte[] str) {
|
||||
int xorByte = 0xAAAA;
|
||||
char[] charRet = new char[str.length / 2];
|
||||
for (int i = 0; i < str.length; i++) {
|
||||
str[i] = (byte) (str[i] ^ encKey[i]);
|
||||
}
|
||||
for (int i = 0; i < (str.length / 2); i++) {
|
||||
char toXor = (char) ((str[i] << 8) | str[i + 1]);
|
||||
charRet[i] = (char) (toXor ^ xorByte);
|
||||
xorByte++;
|
||||
}
|
||||
return String.valueOf(charRet);
|
||||
}
|
||||
|
||||
public static String readDecodedStringAtOffset(SeekableLittleEndianAccessor slea, int offset) {
|
||||
slea.seek(offset);
|
||||
return readDecodedString(slea);
|
||||
}
|
||||
|
||||
public static String readDecodedStringAtOffsetAndReset(SeekableLittleEndianAccessor slea, int offset) {
|
||||
long pos = 0;
|
||||
pos = slea.getPosition();
|
||||
slea.seek(offset);
|
||||
String ret = readDecodedString(slea);
|
||||
slea.seek(pos);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int readValue(LittleEndianAccessor lea) {
|
||||
byte b = lea.readByte();
|
||||
if (b == -128) {
|
||||
return lea.readInt();
|
||||
} else {
|
||||
return ((int) b);
|
||||
}
|
||||
}
|
||||
|
||||
public static float readFloatValue(LittleEndianAccessor lea) {
|
||||
byte b = lea.readByte();
|
||||
if (b == -128) {
|
||||
return lea.readFloat();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.text.NumberFormat;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataEntity;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public class XMLDomMapleData implements MapleData {
|
||||
private Node node;
|
||||
private File imageDataDir;
|
||||
private NumberFormat nf;
|
||||
|
||||
public XMLDomMapleData(FileInputStream fis, File imageDataDir) {
|
||||
try {
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
Document document = documentBuilder.parse(fis);
|
||||
this.node = document.getFirstChild();
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.imageDataDir = imageDataDir;
|
||||
this.nf = NumberFormat.getInstance(Locale.FRANCE);
|
||||
}
|
||||
|
||||
private XMLDomMapleData(Node node) {
|
||||
this.node = node;
|
||||
this.nf = NumberFormat.getInstance(Locale.FRANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleData getChildByPath(String path) {
|
||||
String segments[] = path.split("/");
|
||||
if (segments[0].equals("..")) {
|
||||
return ((MapleData) getParent()).getChildByPath(path.substring(path.indexOf("/") + 1));
|
||||
}
|
||||
|
||||
Node myNode = node;
|
||||
for (int x = 0; x < segments.length; x++) {
|
||||
NodeList childNodes = myNode.getChildNodes();
|
||||
boolean foundChild = false;
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node childNode = childNodes.item(i);
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE && childNode.getAttributes().getNamedItem("name").getNodeValue().equals(segments[x])) {
|
||||
myNode = childNode;
|
||||
foundChild = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundChild) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
XMLDomMapleData ret = new XMLDomMapleData(myNode);
|
||||
ret.imageDataDir = new File(imageDataDir, getName() + "/" + path).getParentFile();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MapleData> getChildren() {
|
||||
List<MapleData> ret = new ArrayList<MapleData>();
|
||||
NodeList childNodes = node.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node childNode = childNodes.item(i);
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
|
||||
XMLDomMapleData child = new XMLDomMapleData(childNode);
|
||||
child.imageDataDir = new File(imageDataDir, getName());
|
||||
ret.add(child);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData() {
|
||||
NamedNodeMap attributes = node.getAttributes();
|
||||
MapleDataType type = getType();
|
||||
switch (type) {
|
||||
case DOUBLE:
|
||||
case FLOAT:
|
||||
case INT:
|
||||
case SHORT: {
|
||||
String value = attributes.getNamedItem("value").getNodeValue();
|
||||
Number nval;
|
||||
|
||||
try {
|
||||
nval = nf.parse(value);
|
||||
}
|
||||
catch(java.text.ParseException pe) {
|
||||
pe.printStackTrace();
|
||||
nval = 0.0f;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case DOUBLE:
|
||||
return nval.doubleValue();
|
||||
case FLOAT:
|
||||
return nval.floatValue();
|
||||
case INT:
|
||||
return nval.intValue();
|
||||
case SHORT:
|
||||
return nval.shortValue();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case STRING:
|
||||
case UOL: {
|
||||
String value = attributes.getNamedItem("value").getNodeValue();
|
||||
return value;
|
||||
}
|
||||
case VECTOR: {
|
||||
String x = attributes.getNamedItem("x").getNodeValue();
|
||||
String y = attributes.getNamedItem("y").getNodeValue();
|
||||
return new Point(Integer.parseInt(x), Integer.parseInt(y));
|
||||
}
|
||||
case CANVAS: {
|
||||
String width = attributes.getNamedItem("width").getNodeValue();
|
||||
String height = attributes.getNamedItem("height").getNodeValue();
|
||||
return new FileStoredPngMapleCanvas(Integer.parseInt(width), Integer.parseInt(height), new File(
|
||||
imageDataDir, getName() + ".png"));
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleDataType getType() {
|
||||
String nodeName = node.getNodeName();
|
||||
if (nodeName.equals("imgdir")) {
|
||||
return MapleDataType.PROPERTY;
|
||||
} else if (nodeName.equals("canvas")) {
|
||||
return MapleDataType.CANVAS;
|
||||
} else if (nodeName.equals("convex")) {
|
||||
return MapleDataType.CONVEX;
|
||||
} else if (nodeName.equals("sound")) {
|
||||
return MapleDataType.SOUND;
|
||||
} else if (nodeName.equals("uol")) {
|
||||
return MapleDataType.UOL;
|
||||
} else if (nodeName.equals("double")) {
|
||||
return MapleDataType.DOUBLE;
|
||||
} else if (nodeName.equals("float")) {
|
||||
return MapleDataType.FLOAT;
|
||||
} else if (nodeName.equals("int")) {
|
||||
return MapleDataType.INT;
|
||||
} else if (nodeName.equals("short")) {
|
||||
return MapleDataType.SHORT;
|
||||
} else if (nodeName.equals("string")) {
|
||||
return MapleDataType.STRING;
|
||||
} else if (nodeName.equals("vector")) {
|
||||
return MapleDataType.VECTOR;
|
||||
} else if (nodeName.equals("null")) {
|
||||
return MapleDataType.IMG_0x00;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleDataEntity getParent() {
|
||||
Node parentNode = node.getParentNode();
|
||||
if (parentNode.getNodeType() == Node.DOCUMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
XMLDomMapleData parentData = new XMLDomMapleData(parentNode);
|
||||
parentData.imageDataDir = imageDataDir.getParentFile();
|
||||
return parentData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return node.getAttributes().getNamedItem("name").getNodeValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<MapleData> iterator() {
|
||||
return getChildren().iterator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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 provider.wz;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataDirectoryEntry;
|
||||
import provider.MapleDataProvider;
|
||||
|
||||
public class XMLWZFile implements MapleDataProvider {
|
||||
private File root;
|
||||
private WZDirectoryEntry rootForNavigation;
|
||||
|
||||
public XMLWZFile(File fileIn) {
|
||||
root = fileIn;
|
||||
rootForNavigation = new WZDirectoryEntry(fileIn.getName(), 0, 0, null);
|
||||
fillMapleDataEntitys(root, rootForNavigation);
|
||||
}
|
||||
|
||||
private void fillMapleDataEntitys(File lroot, WZDirectoryEntry wzdir) {
|
||||
for (File file : lroot.listFiles()) {
|
||||
String fileName = file.getName();
|
||||
if (file.isDirectory() && !fileName.endsWith(".img")) {
|
||||
WZDirectoryEntry newDir = new WZDirectoryEntry(fileName, 0, 0, wzdir);
|
||||
wzdir.addDirectory(newDir);
|
||||
fillMapleDataEntitys(file, newDir);
|
||||
} else if (fileName.endsWith(".xml")) {
|
||||
wzdir.addFile(new WZFileEntry(fileName.substring(0, fileName.length() - 4), 0, 0, wzdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleData getData(String path) {
|
||||
File dataFile = new File(root, path + ".xml");
|
||||
File imageDataDir = new File(root, path);
|
||||
if (!dataFile.exists()) {
|
||||
return null;//bitches
|
||||
}
|
||||
FileInputStream fis;
|
||||
try {
|
||||
fis = new FileInputStream(dataFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException("Datafile " + path + " does not exist in " + root.getAbsolutePath());
|
||||
}
|
||||
final XMLDomMapleData domMapleData;
|
||||
try {
|
||||
domMapleData = new XMLDomMapleData(fis, imageDataDir.getParentFile());
|
||||
} finally {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return domMapleData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapleDataDirectoryEntry getRoot() {
|
||||
return rootForNavigation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package tools;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Frz (Big Daddy)
|
||||
* @author The Real Spookster (some modifications to this beautiful code)
|
||||
*/
|
||||
public class DatabaseConnection {
|
||||
private static String DB_URL = "jdbc:mysql://localhost:3306/heavenms";
|
||||
private static String DB_USER = "root";
|
||||
private static String DB_PASS = "";
|
||||
|
||||
public static final int RETURN_GENERATED_KEYS = 1;
|
||||
|
||||
private static ThreadLocal<Connection> con = new ThreadLocalConnection();
|
||||
|
||||
public static Connection getConnection() {
|
||||
Connection c = con.get();
|
||||
try {
|
||||
c.getMetaData();
|
||||
} catch (SQLException e) { // connection is dead, therefore discard old object 5ever
|
||||
con.remove();
|
||||
c = con.get();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private static class ThreadLocalConnection extends ThreadLocal<Connection> {
|
||||
|
||||
@Override
|
||||
protected Connection initialValue() {
|
||||
try {
|
||||
Class.forName("com.mysql.jdbc.Driver"); // touch the mysql driver
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.out.println("[SEVERE] SQL Driver Not Found. Consider death by clams.");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
|
||||
} catch (SQLException e) {
|
||||
System.out.println("[SEVERE] Unable to make database connection.");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user