├── .gitignore ├── LICENSE ├── README.md ├── configs ├── game.yml ├── server.yml └── world.yml ├── images └── game1.png ├── pom.xml ├── scripts ├── item │ └── consume │ │ ├── 2431174.js │ │ └── 2432526.js ├── map │ ├── onFirstUserEnter │ │ └── StageMsg_crack.js │ └── onUserEnter │ │ ├── explorationPoint.js │ │ ├── go40000.js │ │ └── party2FirstIn.js ├── npc │ ├── 9220050.js │ ├── GoSchool.js │ ├── MapleEquipBuildup.js │ ├── Test.js │ ├── guild_move.js │ ├── guild_proc.js │ ├── jobTransfer.js │ ├── mParkShuttle.js │ ├── make_alert.js │ ├── npc_1012102.js │ ├── npc_9220050.js │ ├── party2_enter.js │ ├── party2_out.js │ ├── party2_play.js │ ├── unityPortal.js │ └── victoria_taxi.js ├── portal │ ├── ludi_s1Clear.js │ ├── ludi_s2Clear.js │ ├── market01.js │ ├── out_guild.js │ ├── out_profession.js │ ├── party2_exit.js │ ├── party2_rp.js │ ├── profession01.js │ └── stage6_portal.js └── quest │ ├── q29900s.js │ ├── q29901s.js │ ├── q29902s.js │ ├── q29903s.js │ ├── q36102s.js │ ├── q501044s.js │ └── q7707s.js ├── sql ├── drop_data.sql └── maple.sql └── src └── main ├── java └── im │ └── cave │ └── ms │ ├── client │ ├── Account.java │ ├── Clock.java │ ├── HotTimeReward.java │ ├── MapleClient.java │ ├── MapleDailyGift.java │ ├── Record.java │ ├── RecordManager.java │ ├── character │ │ ├── CharLook.java │ │ ├── CharStats.java │ │ ├── DamageCalc.java │ │ ├── DamageSkinSaveData.java │ │ ├── ExpIncreaseInfo.java │ │ ├── KeyBind.java │ │ ├── LinkSkill.java │ │ ├── Macro.java │ │ ├── MapleCharacter.java │ │ ├── MapleKeyMap.java │ │ ├── NonCombatStatDayLimit.java │ │ ├── Option.java │ │ ├── PortableChair.java │ │ ├── Stat.java │ │ ├── items │ │ │ ├── AuctionRecord.java │ │ │ ├── CashShopItem.java │ │ │ ├── Equip.java │ │ │ ├── ExceptionItem.java │ │ │ ├── FlameStats.java │ │ │ ├── Inventory.java │ │ │ ├── InventoryOperation.java │ │ │ ├── Item.java │ │ │ ├── ItemBuffs.java │ │ │ ├── ItemOption.java │ │ │ ├── ItemSkill.java │ │ │ ├── PetItem.java │ │ │ ├── PotionPot.java │ │ │ ├── ScrollUpgradeInfo.java │ │ │ └── WishedItem.java │ │ ├── job │ │ │ ├── GM.java │ │ │ ├── JobManager.java │ │ │ ├── MapleJob.java │ │ │ └── adventurer │ │ │ │ ├── Archer.java │ │ │ │ ├── Beginner.java │ │ │ │ ├── Magician.java │ │ │ │ ├── Pirate.java │ │ │ │ ├── Thief.java │ │ │ │ └── Warrior.java │ │ ├── legion │ │ │ ├── Legion.java │ │ │ └── LegionEntry.java │ │ ├── potential │ │ │ ├── CharacterPotential.java │ │ │ └── CharacterPotentialMan.java │ │ ├── skill │ │ │ ├── AttackInfo.java │ │ │ ├── BurnedInfo.java │ │ │ ├── ForceAtom.java │ │ │ ├── ForceAtomInfo.java │ │ │ ├── HitInfo.java │ │ │ ├── MatrixInventory.java │ │ │ ├── MatrixSkill.java │ │ │ ├── MatrixSlot.java │ │ │ ├── MobAttackInfo.java │ │ │ ├── MobSkillInfo.java │ │ │ ├── Skill.java │ │ │ └── StopForceAtom.java │ │ └── temp │ │ │ ├── CharacterTemporaryStat.java │ │ │ ├── TemporaryStatBase.java │ │ │ ├── TemporaryStatManager.java │ │ │ ├── TwoStateTemporaryStat.java │ │ │ └── statup │ ├── field │ │ ├── AffectedArea.java │ │ ├── Effect.java │ │ ├── FieldAttackObj.java │ │ ├── FieldEffect.java │ │ ├── Foothold.java │ │ ├── MapleMap.java │ │ ├── Portal.java │ │ ├── QuickMoveInfo.java │ │ ├── movement │ │ │ ├── MovePathAttribute.java │ │ │ ├── Movement.java │ │ │ ├── MovementAction.java │ │ │ ├── MovementAngle.java │ │ │ ├── MovementBase.java │ │ │ ├── MovementFlyingBlock.java │ │ │ ├── MovementInfo.java │ │ │ ├── MovementJump.java │ │ │ ├── MovementNormal.java │ │ │ ├── MovementStartFallDown.java │ │ │ ├── MovementStatChange.java │ │ │ ├── MovementTeleport.java │ │ │ └── MovementUNK.java │ │ ├── obj │ │ │ ├── Android.java │ │ │ ├── Drop.java │ │ │ ├── Familiar.java │ │ │ ├── MapleMapObj.java │ │ │ ├── Pet.java │ │ │ ├── Reactor.java │ │ │ ├── Summon.java │ │ │ ├── mob │ │ │ │ ├── EscortDest.java │ │ │ │ ├── ForcedMobStat.java │ │ │ │ ├── Mob.java │ │ │ │ ├── MobGen.java │ │ │ │ ├── MobSkill.java │ │ │ │ ├── MobSkillAttackInfo.java │ │ │ │ ├── MobStat │ │ │ │ ├── MobStat.java │ │ │ │ ├── MobStats │ │ │ │ └── MobTemporaryStat.java │ │ │ └── npc │ │ │ │ ├── Npc.java │ │ │ │ └── shop │ │ │ │ ├── BuyLimitInfo.java │ │ │ │ ├── NpcShop.java │ │ │ │ └── NpcShopItem.java │ │ └── obstacleatom │ │ │ ├── ObstacleAtomInfo.java │ │ │ ├── ObstacleDiagonalInfo.java │ │ │ ├── ObstacleInRowInfo.java │ │ │ └── ObstacleRadianInfo.java │ ├── multiplayer │ │ ├── Express.java │ │ ├── MapleNotes.java │ │ ├── friend │ │ │ └── Friend.java │ │ ├── guilds │ │ │ ├── Guild.java │ │ │ ├── GuildGrade.java │ │ │ ├── GuildMember.java │ │ │ ├── GuildRequestor.java │ │ │ └── GuildSkill.java │ │ ├── miniroom │ │ │ ├── ChatRoom.java │ │ │ ├── MiniRoom.java │ │ │ ├── RPSRoom.java │ │ │ └── TradeRoom.java │ │ └── party │ │ │ ├── Party.java │ │ │ ├── PartyMember.java │ │ │ ├── PartyQuest.java │ │ │ ├── PartyResult.java │ │ │ └── TownPortal.java │ ├── quest │ │ ├── Quest.java │ │ ├── QuestManager.java │ │ ├── progress │ │ │ ├── QuestProgressItemRequirement.java │ │ │ ├── QuestProgressLevelRequirement.java │ │ │ ├── QuestProgressMobRequirement.java │ │ │ ├── QuestProgressMoneyRequirement.java │ │ │ ├── QuestProgressRequirement.java │ │ │ └── QuestProgressRequirementType.java │ │ ├── requirement │ │ │ ├── QuestStartCompletionRequirement.java │ │ │ ├── QuestStartItemRequirement.java │ │ │ ├── QuestStartJobRequirement.java │ │ │ ├── QuestStartMarriageRequirement.java │ │ │ ├── QuestStartMaxLevelRequirement.java │ │ │ ├── QuestStartMinStatRequirement.java │ │ │ ├── QuestStartRequirement.java │ │ │ └── QuestStartRequirementType.java │ │ └── reward │ │ │ ├── QuestBuffItemReward.java │ │ │ ├── QuestExpReward.java │ │ │ ├── QuestItemReward.java │ │ │ ├── QuestMoneyReward.java │ │ │ ├── QuestPopReward.java │ │ │ ├── QuestReward.java │ │ │ └── QuestRewardType.java │ └── storage │ │ ├── Locker.java │ │ ├── Storage.java │ │ └── Trunk.java │ ├── configs │ ├── Config.java │ ├── ServerConfig.java │ └── WorldConfig.java │ ├── connection │ ├── crypto │ │ ├── AES.java │ │ ├── AESCipher.java │ │ ├── CIGCipher.java │ │ └── TripleDESCipher.java │ ├── db │ │ ├── DataBaseManager.java │ │ └── InlinedIntArrayConverter.java │ ├── netty │ │ ├── InPacket.java │ │ ├── MaplePacketDecoder.java │ │ ├── MaplePacketEncoder.java │ │ ├── OutPacket.java │ │ ├── Packet.java │ │ ├── ServerAcceptor.java │ │ └── ServerInitializer.java │ ├── packet │ │ ├── AndroidPacket.java │ │ ├── AuctionPacket.java │ │ ├── CashShopPacket.java │ │ ├── FamiliarPacket.java │ │ ├── FieldAttackObjPacket.java │ │ ├── FieldPacket.java │ │ ├── LoginPacket.java │ │ ├── MessagePacket.java │ │ ├── MiniRoomPacket.java │ │ ├── MobPacket.java │ │ ├── NpcPacket.java │ │ ├── PacketHelper.java │ │ ├── PetPacket.java │ │ ├── QuestPacket.java │ │ ├── ReactorPacket.java │ │ ├── ServerPacket.java │ │ ├── SummonPacket.java │ │ ├── UserPacket.java │ │ ├── UserRemote.java │ │ ├── WorldPacket.java │ │ ├── opcode │ │ │ ├── RecvOpcode.java │ │ │ ├── SendOpcode.java │ │ │ └── Send_opcode_176.bak │ │ └── result │ │ │ ├── ExpressResult.java │ │ │ ├── FameResult.java │ │ │ ├── GuildResult.java │ │ │ ├── HotTimeRewardResult.java │ │ │ ├── InGameDirectionEvent.java │ │ │ └── MapleNotesResult.java │ └── server │ │ ├── AbstractServer.java │ │ ├── AbstractServerHandler.java │ │ ├── ErrorPacketHandler.java │ │ ├── Server.java │ │ ├── auction │ │ ├── Auction.java │ │ └── AuctionHandler.java │ │ ├── cashshop │ │ ├── CashShopHandler.java │ │ └── CashShopServer.java │ │ ├── channel │ │ ├── ChannelHandler.java │ │ ├── CommandExecutor.java │ │ ├── MapleChannel.java │ │ └── handler │ │ │ ├── CashItemActuator.java │ │ │ ├── ChatHandler.java │ │ │ ├── InventoryHandler.java │ │ │ ├── MobHandler.java │ │ │ ├── NpcHandler.java │ │ │ ├── PetHandler.java │ │ │ ├── QuestHandler.java │ │ │ ├── UserHandler.java │ │ │ └── WorldHandler.java │ │ ├── login │ │ ├── LoginServer.java │ │ ├── LoginServerHandler.java │ │ └── handler │ │ │ ├── CharOperationHandler.java │ │ │ ├── CharlistRequestHandler.java │ │ │ ├── OfficialLoginHandler.java │ │ │ ├── PasswordLoginHandler.java │ │ │ └── ServerListHandler.java │ │ ├── service │ │ ├── CathingScheduledThreadPoolExecutor.java │ │ ├── EventManager.java │ │ └── task │ │ │ ├── ExpiredItemRecycle.java │ │ │ └── RecordClear.java │ │ └── world │ │ └── World.java │ ├── constants │ ├── GameConstants.java │ ├── ItemConstants.java │ ├── JobConstants.java │ ├── MatrixConstants.java │ ├── QuestConstants.java │ ├── ServerConstants.java │ └── SkillConstants.java │ ├── enums │ ├── ArcEnchantType.java │ ├── AssistType.java │ ├── AuctionAction.java │ ├── BaseStat.java │ ├── BodyPart.java │ ├── BroadcastMsgType.java │ ├── CashItemType.java │ ├── CashShopCurrencyType.java │ ├── CharMask.java │ ├── CharPotGrade.java │ ├── ChatRoomType.java │ ├── ChatType.java │ ├── ClockType.java │ ├── Command.java │ ├── DamageSkinType.java │ ├── DimensionalMirror.java │ ├── DropEnterType.java │ ├── DropLeaveType.java │ ├── DropTimeoutStrategy.java │ ├── EnchantStat.java │ ├── EnterType.java │ ├── EquipAttribute.java │ ├── EquipBaseStat.java │ ├── EquipPrefix.java │ ├── EquipSpecialAttribute.java │ ├── EquipmentEnchantType.java │ ├── ExpIncreaseInfoFlags.java │ ├── ExpressAction.java │ ├── FameAction.java │ ├── FamiliarGrade.java │ ├── FamiliarType.java │ ├── FieldEffectType.java │ ├── FieldOption.java │ ├── FieldType.java │ ├── FlameStat.java │ ├── ForceAtomEnum.java │ ├── FriendFlag.java │ ├── FriendType.java │ ├── Gender.java │ ├── GreyFieldType.java │ ├── GuildOption.java │ ├── GuildRight.java │ ├── GuildType.java │ ├── HotTimeRewardResultType.java │ ├── InGameDirectionEventType.java │ ├── InstanceTableType.java │ ├── InventoryOperationType.java │ ├── InventoryType.java │ ├── ItemGrade.java │ ├── ItemOptionType.java │ ├── ItemState.java │ ├── JobType.java │ ├── LoginStatus.java │ ├── LoginType.java │ ├── MapTransferType.java │ ├── MapleNotesType.java │ ├── MatrixStateType.java │ ├── MatrixUpdateType.java │ ├── MessageType.java │ ├── MiniRoomType.java │ ├── MobSkillStat.java │ ├── MoveAbility.java │ ├── NpcMessageType.java │ ├── ObstacleAtomCreateType.java │ ├── PartyQuestType.java │ ├── PartyType.java │ ├── PetSkill.java │ ├── PortalType.java │ ├── PrivateStatusIDFlag.java │ ├── QuestStatus.java │ ├── QuestType.java │ ├── QuickMoveType.java │ ├── RecordType.java │ ├── RemoveMobType.java │ ├── RequiredJob.java │ ├── RoomLeaveType.java │ ├── ScrollStat.java │ ├── ServerType.java │ ├── ShopRequestType.java │ ├── ShopResultType.java │ ├── SkillStat.java │ ├── SpecStat.java │ ├── SpellTraceScrollType.java │ ├── TSIndex.java │ ├── TextEffectType.java │ ├── TrunkOpType.java │ ├── UIType.java │ ├── UserEffectType.java │ ├── WeatherEffNoticeType.java │ └── WhisperType.java │ ├── provider │ ├── data │ │ ├── DropData.java │ │ ├── EffectData.java │ │ ├── ItemData.java │ │ ├── MapData.java │ │ ├── MobData.java │ │ ├── NpcData.java │ │ ├── QuestData.java │ │ ├── ReactorData.java │ │ ├── SkillData.java │ │ ├── StringData.java │ │ └── VCoreData.java │ ├── info │ │ ├── AndroidInfo.java │ │ ├── CashItemInfo.java │ │ ├── DropInfo.java │ │ ├── FamiliarInfo.java │ │ ├── ItemInfo.java │ │ ├── ItemRewardInfo.java │ │ ├── MakingSkillRecipe.java │ │ ├── PetInfo.java │ │ ├── QuestInfo.java │ │ ├── SkillInfo.java │ │ ├── SkillOption.java │ │ └── VCore.java │ └── wz │ │ ├── MapleCanvas.java │ │ ├── MapleData.java │ │ ├── MapleDataDirectoryEntry.java │ │ ├── MapleDataEntity.java │ │ ├── MapleDataEntry.java │ │ ├── MapleDataFileEntry.java │ │ ├── MapleDataProvider.java │ │ ├── MapleDataProviderFactory.java │ │ ├── MapleDataTool.java │ │ └── MapleDataType.java │ ├── scripting │ ├── AbstractPlayerInteraction.java │ ├── AbstractScriptManager.java │ ├── ScriptException.java │ ├── item │ │ ├── ItemScriptAction.java │ │ └── ItemScriptManager.java │ ├── map │ │ ├── MapScriptManager.java │ │ └── MapScriptMethods.java │ ├── npc │ │ ├── NpcConversationManager.java │ │ ├── NpcScriptInfo.java │ │ └── NpcScriptManager.java │ ├── portal │ │ ├── PortalPlayerInteraction.java │ │ └── PortalScriptManager.java │ └── quest │ │ ├── QuestActionManager.java │ │ └── QuestScriptManager.java │ └── tools │ ├── DateUtil.java │ ├── HexTool.java │ ├── Pair.java │ ├── Position.java │ ├── Randomizer.java │ ├── Rect.java │ ├── StringUtil.java │ ├── Triple.java │ ├── Tuple.java │ ├── Util.java │ └── exception │ ├── CrackException.java │ └── SkillException.java └── resources ├── hibernate.cfg.xml ├── logback.xml └── rebel-remote.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | target 3 | wz 4 | .idea/ 5 | ms.iml 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ms 2 | 3 | **maplestory emulator** 4 | 5 | ~~只能进游戏逛街😓~~ 6 | 7 | ![game](https://raw.githubusercontent.com/fairms/MapleServer/v179/images/game1.png) 8 | 9 | ###### **参考项目:** 10 | 11 | - [MapleEllinel](https://github.com/mechaviv/MapleEllinel-v203.4) 12 | - [AzureV316](https://github.com/SoulGirlJP/AzureV316) 13 | - [MapleStory143](https://github.com/mimilewis/MapleStory143) 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /configs/game.yml: -------------------------------------------------------------------------------- 1 | # LL:装备等级 2 | # 使用JS公式计算 3 | # 普通装备 4 | STAR_FORCE: 5 | COST: LL * 4 + 3 6 | SUCCESS: 7 | DESTROY: 8 | # 极真装备 9 | SUPERIOR_STAR_FORCE: 10 | COST: LL * 4 + 3 11 | SUCCESS: 12 | DESTROY: -------------------------------------------------------------------------------- /configs/server.yml: -------------------------------------------------------------------------------- 1 | AUTOMATIC_REGISTER: true 2 | SHOW_UNKNOWN_PACKET: false 3 | DEBUG: false 4 | CLOSED_JOBS: 5 | - -------------------------------------------------------------------------------- /images/game1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairms/MapleServer/70c8914a083e2f24555ba4a410136fec5672c01e/images/game1.png -------------------------------------------------------------------------------- /scripts/item/consume/2431174.js: -------------------------------------------------------------------------------- 1 | /* 2 | 荣誉勋章 3 | */ 4 | function start(im) { 5 | let Randomizer = Java.type("im.cave.ms.tools.Randomizer"); 6 | im.addHonerPoint(Randomizer.rand(10, 120)); 7 | return true; 8 | } -------------------------------------------------------------------------------- /scripts/item/consume/2432526.js: -------------------------------------------------------------------------------- 1 | /* 2 | 伤害皮肤 3 | 键盘战士 4 | */ 5 | function start(im) { 6 | im.setDamageSkin(2432526); 7 | im.consumeItem(2432526, 1); 8 | return true; 9 | } -------------------------------------------------------------------------------- /scripts/map/onFirstUserEnter/StageMsg_crack.js: -------------------------------------------------------------------------------- 1 | /** 玩具城组队关卡初始化 **/ 2 | const stage1MapId = 922010100; 3 | const stage2MapId = 922010400; 4 | const stage2Inner = Array.of(922010401, 922010402, 922010403, 922010404, 922010405); 5 | const stage3MapId = 922010600; 6 | const stage4MapId = 922010700; 7 | const stage5MapId = 922010800; 8 | const stage6MapId = 922010900; 9 | 10 | function start() { 11 | let mapId = ms.getMapId(); 12 | let party = ms.getChar().getParty(); 13 | let partyQuest = party.getPartyQuest(); 14 | if (partyQuest == null) { 15 | return; 16 | } 17 | ms.disablePortal("next00"); 18 | switch (mapId) { 19 | case stage1MapId: 20 | break 21 | case stage2MapId: 22 | for (let hole of stage2Inner) { 23 | let holeMap = party.getOrCreateFieldById(hole); 24 | partyQuest.addMap(holeMap); 25 | } 26 | break 27 | case stage3MapId: 28 | let answerOptions = []; 29 | for (let i = 0; i < 10; i++) { 30 | answerOptions.push(randomNum(0, 2)) 31 | } 32 | partyQuest.setParam1(answerOptions.toString()); 33 | break 34 | case stage4MapId: 35 | break; 36 | case stage5MapId: //计算题 37 | break; 38 | case stage6MapId: //召唤阿莉莎 39 | let map = chr.getMap(); 40 | map.spawnMob(mob, x, y); 41 | break; 42 | } 43 | } 44 | 45 | 46 | //生成从minNum到maxNum的随机数 47 | function randomNum(minNum, maxNum) { 48 | switch (arguments.length) { 49 | case 1: 50 | return parseInt(Math.random() * minNum + 1, 10); 51 | case 2: 52 | return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10); 53 | default: 54 | return 0; 55 | } 56 | } -------------------------------------------------------------------------------- /scripts/map/onUserEnter/explorationPoint.js: -------------------------------------------------------------------------------- 1 | const hidden = Array(); 2 | 3 | function start() { 4 | ms.npcDisableInfo(hidden); 5 | if (ms.getMapId() === 104000000) { 6 | ms.showEffect("maplemap/enter/104000000", 0); 7 | } 8 | } -------------------------------------------------------------------------------- /scripts/map/onUserEnter/go40000.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | } -------------------------------------------------------------------------------- /scripts/map/onUserEnter/party2FirstIn.js: -------------------------------------------------------------------------------- 1 | /** 玩具城组队:初始 **/ 2 | const hidden = Array(); 3 | const timeLimit = 1800; 4 | 5 | function start() { 6 | 7 | let chr = ms.getChar(); 8 | ms.npcDisableInfo(hidden); 9 | ms.beginClock(1800); 10 | chr.getParty().setPQProgress(0); 11 | let itemQuantity = chr.getItemQuantity(4001022); 12 | chr.consumeItem(4001022, itemQuantity); 13 | 14 | } -------------------------------------------------------------------------------- /scripts/npc/9220050.js: -------------------------------------------------------------------------------- 1 | /* 2 | @npc: 3 | @map: 4 | @desc: 5 | */ 6 | 7 | function start() { 8 | cm.dispose(); 9 | cm.runNPCScript("MapleEquipBuildup", 0); 10 | } -------------------------------------------------------------------------------- /scripts/npc/GoSchool.js: -------------------------------------------------------------------------------- 1 | /* 2 | @npc: 3 | @map: 4 | @desc: 5 | */ 6 | 7 | function start() { 8 | const res = cm.sendAskYesNo("你好吗?"); 9 | cm.serverMsg(res); 10 | cm.dispose(); 11 | } -------------------------------------------------------------------------------- /scripts/npc/MapleEquipBuildup.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | const HashMap = Java.type('java.util.HashMap'); 3 | const options = new HashMap(); 4 | options.put(null, '测试功能:'); 5 | options.put(0, '更换发型'); 6 | options.put(1, '打开次元之镜'); 7 | options.put(2, '升级'); 8 | options.put(3, '转职'); 9 | options.put(4, '获取当前地图怪物'); 10 | options.put(5, '获取当前地图掉落'); 11 | options.put(6, '任务查看'); 12 | let select = cm.sendAskMenu(options); 13 | cm.dropMessage(select); 14 | if (select === 0) { 15 | const options = [31050, 31040, 31000]; 16 | const option = cm.sendAskAvatar("请选择:", 5150052, options); 17 | } else if (select === 1) { 18 | cm.openUnityPortal(); 19 | } else if (select === 3) { 20 | cm.dispose(); 21 | cm.runNPCScript("jobTransfer", 0); 22 | return; 23 | } 24 | cm.dispose(); 25 | } -------------------------------------------------------------------------------- /scripts/npc/Test.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | const UIType = Java.type('im.cave.ms.enums.UIType'); 3 | console.log(UIType.UI_STAT.getVal()) 4 | let Randomizer = Java.type("im.cave.ms.tools.Randomizer"); 5 | console.log(Randomizer.rand(20, 2000)); 6 | } -------------------------------------------------------------------------------- /scripts/npc/guild_move.js: -------------------------------------------------------------------------------- 1 | /* 2 | @npc: 3 | @map: 4 | @desc: 5 | */ 6 | 7 | const map = 200000301; 8 | 9 | function start() { 10 | let res = cm.sendAskYesNo("你好。我是负责家族支援工作的蕾雅。为了工作方便,我来到了英雄公馆,为大家提供帮助。你想到英雄公馆去处理家族相关事务吗?"); 11 | if (res === 0) { 12 | cm.sendNext("想去英雄公馆的话,请再来找我。"); 13 | } else if (res === 1) { 14 | if (cm.sendNext("好的,我马上把你送过去。") === 1) { 15 | cm.updateRecord("RETURN_MAP", map, cm.getMapId()); 16 | cm.warp(map); 17 | } 18 | } 19 | 20 | cm.dispose(); 21 | } -------------------------------------------------------------------------------- /scripts/npc/jobTransfer.js: -------------------------------------------------------------------------------- 1 | /* 2 | 转职脚本 3 | todo 4 | */ 5 | 6 | function start() { 7 | let HashMap = Java.type('java.util.HashMap'); 8 | let options = new HashMap(); 9 | const jobId = cm.getJob(); 10 | let advancedJobs = cm.getAdvancedJobs(jobId); 11 | if (advancedJobs.size() === 0) { 12 | cm.sendSayOkay("已经完成所有转职。"); 13 | } else { 14 | options.put(null, "请选择你的路线"); 15 | for (let advancedJob of advancedJobs) { 16 | options.put(advancedJob.getJob(), advancedJob.getName()); 17 | console.log(advancedJob.getName()) 18 | } 19 | const selected = cm.sendAskMenu(options); 20 | if (selected > 0) { 21 | let jobReqLev = cm.getJobReqLev(selected); 22 | if (cm.getLevel() < jobReqLev) { 23 | cm.sendSayOkay("等级不足!"); 24 | } else { 25 | cm.changeJob(selected); 26 | cm.sendSayOkay("完成转职了。") 27 | } 28 | } 29 | } 30 | cm.dispose(); 31 | } -------------------------------------------------------------------------------- /scripts/npc/mParkShuttle.js: -------------------------------------------------------------------------------- 1 | const map = 951000000; 2 | 3 | function start() { 4 | if (cm.getMapId() === map) { 5 | const res = cm.sendAskYesNo("你好。怪物公园客车竭诚为大家提供最好的服务。你想回到原来的村里去吗?"); 6 | if (res === 1) { 7 | const value = cm.getRecordValue("RETURN_MAP", map); 8 | cm.warp(value !== 0 ? value : 10000000); 9 | } 10 | } else { 11 | const res = cm.sendAskYesNo("亲爱的顾客,你想到充满了欢乐的休彼德蔓的怪物公园去吗?"); 12 | if (res === 0) { 13 | cm.sendSayOkay("那么等你考虑好了再来吧!"); 14 | } else if (res === 1) { 15 | if (cm.sendNext("那么坐好了,我们马上出发!") > 0) { 16 | cm.updateRecord("RETURN_MAP", map, cm.getMapId()); 17 | cm.warp(map); 18 | } 19 | } 20 | } 21 | cm.dispose(); 22 | } -------------------------------------------------------------------------------- /scripts/npc/make_alert.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | cm.openUI(); 3 | cm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/npc/npc_1012102.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | cm.dropMessage("sorry"); 3 | cm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/npc/npc_9220050.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | const HashMap = Java.type('java.util.HashMap'); 3 | const options = new HashMap(); 4 | options.put(null, '测试测试测试测试:'); 5 | options.put(0, '更换发型'); 6 | options.put(1, '打开次元之镜'); 7 | options.put(2, '升级'); 8 | options.put(3, '重置人物'); 9 | options.put(4, '获取当前地图怪物'); 10 | options.put(5, '获取当前地图掉落'); 11 | options.put(6, '任务查看'); 12 | var select = cm.sendAskMenu(options); 13 | cm.dropMessage(select); 14 | if (select === 0) { 15 | const options = [31050, 31040, 31000]; 16 | const option = cm.sendAskAvatar("请选择:", 5150052, options); 17 | cm.dropMessage(option); 18 | } else if (select === 1) { 19 | cm.openUnityPortal(); 20 | } 21 | cm.dispose(); 22 | } -------------------------------------------------------------------------------- /scripts/npc/party2_out.js: -------------------------------------------------------------------------------- 1 | /** 玩具城组队:退场处理 **/ 2 | const RecordType = Java.type("im.cave.ms.enums.RecordType"); 3 | 4 | const enterMap = 221023300; 5 | const stage1NPCId = 2040036; 6 | const stage2NPCId = 2040036; 7 | const stage3NPCId = 2040036; 8 | const outMap = 922010000; 9 | 10 | function start() { 11 | let chr = cm.getChar(); 12 | if (chr.getMapId() === outMap) { 13 | out(enterMap); 14 | } else { 15 | if (cm.sendAskYesNo("你确放弃任务,从这里出去重新开始吗?") === 1) { 16 | out(outMap); 17 | } 18 | } 19 | cm.dispose(); 20 | } 21 | 22 | function out(mapId) { 23 | cm.warp(mapId); 24 | if (mapId === enterMap) { 25 | cm.updateRecord(RecordType.NPC_TALK_COUNT, stage1NPCId, 0); 26 | cm.updateRecord(RecordType.NPC_TALK_COUNT, stage2NPCId, 0); 27 | cm.updateRecord(RecordType.NPC_TALK_COUNT, stage3NPCId, 0); 28 | } 29 | } -------------------------------------------------------------------------------- /scripts/npc/unityPortal.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | cm.openUnityPortal(); 3 | cm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/npc/victoria_taxi.js: -------------------------------------------------------------------------------- 1 | const maps = Array(100000000, 104000000, 102000000, 101000000, 103000000, 120000000, 105000000); 2 | 3 | function start() { 4 | let res = cm.sendNext("你好~!我是#p1012000#。你想快速又安全地移动到其他村庄吗? " + 5 | "那么就请使用令客户百分百满意的#b#p1012000##k吧。这次我给你免费优待!我将会送你去想去的地方。"); 6 | if (res > 0) { 7 | const HashMap = Java.type('java.util.HashMap'); 8 | const options = new HashMap(); 9 | options.put(null, '请选择目的地。'); 10 | for (let a = 0; a < maps.length; a++) { 11 | if (maps[a] !== cm.getMapId()) { 12 | options.put(a, "#m" + maps[a] + "#"); 13 | } 14 | } 15 | const select = cm.sendAskMenu(options); 16 | cm.dropMessage("选择" + select); 17 | if (select >= 0 && select < maps.length) { 18 | const res = cm.sendAskYesNo("看样子, 你好像已经没有什么事情需要在这里做了。确定要移动到#b#m" + maps[select] + "##k村庄吗?"); 19 | if (res === 1) { 20 | cm.warp(maps[select]); 21 | } else if (res === 0) { 22 | cm.sendSayOkay("如果你想移动到其他村庄, 请随时使用我们的出租车~"); 23 | } 24 | } 25 | } 26 | cm.dispose(); 27 | } -------------------------------------------------------------------------------- /scripts/portal/ludi_s1Clear.js: -------------------------------------------------------------------------------- 1 | function enter(pm) { 2 | let chr = pm.getChar(); 3 | let party = chr.getParty(); 4 | let partyQuest = party.getPartyQuest(); 5 | if (partyQuest.hasPassed(1)) { 6 | let nextMap = party.getOrCreateFieldById(922010400); 7 | partyQuest.addMap(nextMap); 8 | pm.warp(nextMap); 9 | return true 10 | } 11 | return false; 12 | } -------------------------------------------------------------------------------- /scripts/portal/ludi_s2Clear.js: -------------------------------------------------------------------------------- 1 | function enter(pm) { 2 | let chr = pm.getChar(); 3 | let party = chr.getParty(); 4 | let partyQuest = party.getPartyQuest(); 5 | if (partyQuest.hasPassed(2)) { 6 | let nextMap = party.getOrCreateFieldById(922010600); 7 | partyQuest.addMap(nextMap); 8 | pm.warp(nextMap); 9 | return true 10 | } 11 | return false; 12 | } -------------------------------------------------------------------------------- /scripts/portal/market01.js: -------------------------------------------------------------------------------- 1 | function enter(pm) { 2 | pm.warp(910000000); 3 | return true; 4 | } -------------------------------------------------------------------------------- /scripts/portal/out_guild.js: -------------------------------------------------------------------------------- 1 | const map = 200000301; 2 | const npc_Leia = 2010011; 3 | 4 | function enter(pm) { 5 | const returnMap = pm.getRecordValue("RETURN_MAP", map); 6 | if (returnMap > 0) { 7 | let sp = pm.findSPNearNpc(returnMap, npc_Leia); 8 | pm.warp(returnMap, sp); 9 | return true; 10 | } else { 11 | pm.warp(100000000, 0); 12 | pm.getChar().enableAction(); 13 | return false; 14 | } 15 | } -------------------------------------------------------------------------------- /scripts/portal/out_profession.js: -------------------------------------------------------------------------------- 1 | const RecordType = Java.type("im.cave.ms.enums.RecordType"); 2 | const map = 910001000; 3 | 4 | function enter(pm) { 5 | const returnMap = pm.getRecordValue("RETURN_MAP", map); 6 | if (returnMap > 0) { 7 | pm.warp(returnMap, "profession"); 8 | return true; 9 | } else { 10 | pm.getChar().enableAction(); 11 | return false; 12 | } 13 | } -------------------------------------------------------------------------------- /scripts/portal/party2_exit.js: -------------------------------------------------------------------------------- 1 | function enter(pm) { 2 | pm.warp(910002000); 3 | return true; 4 | } -------------------------------------------------------------------------------- /scripts/portal/party2_rp.js: -------------------------------------------------------------------------------- 1 | const FieldEffect = Java.type("im.cave.ms.client.field.FieldEffect"); 2 | 3 | function enter(pm) { 4 | let chr = pm.getChar(); 5 | let map = chr.getMap(); 6 | let partyQuest = chr.getParty().getPartyQuest(); 7 | if (partyQuest == null) { 8 | return false; 9 | } 10 | let portalName = pm.getPortalName(); 11 | chr.chatMessage(portalName); 12 | if (portalName.startsWith("pt")) { 13 | let num = portalName.replace("pt", ""); 14 | let level = Math.floor(parseInt(num) / 10); 15 | let pick = num % 10 16 | let answer = partyQuest.getParam1(); 17 | let answerOptions = answer.split(','); 18 | if (answerOptions[level] === pick.toString()) { 19 | map.addEffectAndBroadcast(FieldEffect.objectStateByString(portalName.replace("pt", "an"))); 20 | chr.teleport("np0" + level); 21 | chr.enableAction(); 22 | if (level === 9) { 23 | cm.fieldEffect(FieldEffect.screen("quest/party/clear")); 24 | cm.fieldEffect(FieldEffect.playSound("Party1/Clear", 100)); 25 | party.giveExpInProgress(300); 26 | partyQuest.pass(3); 27 | party.setPQProgress(Math.floor(100 / (6 * 3))); 28 | } 29 | return true; 30 | } else { 31 | chr.teleport("npFail"); 32 | return false; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /scripts/portal/profession01.js: -------------------------------------------------------------------------------- 1 | const RecordType = Java.type("im.cave.ms.enums.RecordType"); 2 | const map = 951000000; 3 | 4 | function enter(pm) { 5 | pm.warp(map); 6 | pm.updateRecord(RecordType.RETURN_MAP, map, pm.getMapId()) 7 | return true; 8 | } -------------------------------------------------------------------------------- /scripts/portal/stage6_portal.js: -------------------------------------------------------------------------------- 1 | function enter(pm) { 2 | let chr = pm.getChar(); 3 | let party = chr.getParty(); 4 | let partyQuest = party.getPartyQuest(); 5 | if (partyQuest.hasPassed(3)) { 6 | let nextMap = party.getOrCreateFieldById(922010700); 7 | partyQuest.addMap(nextMap); 8 | party.warp(nextMap); 9 | return true 10 | } 11 | return false; 12 | } -------------------------------------------------------------------------------- /scripts/quest/q29900s.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | qm.startQuest(); 3 | qm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/quest/q29901s.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | qm.startQuest(); 3 | qm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/quest/q29902s.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | qm.startQuest(); 3 | qm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/quest/q29903s.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | qm.startQuest(); 3 | qm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/quest/q36102s.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | qm.startQuest(); 3 | qm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/quest/q501044s.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | qm.startQuest(); 3 | qm.dispose(); 4 | } -------------------------------------------------------------------------------- /scripts/quest/q7707s.js: -------------------------------------------------------------------------------- 1 | function start() { 2 | qm.startQuest(); 3 | qm.dispose(); 4 | } -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/HotTimeReward.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import lombok.Data; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | 12 | import static im.cave.ms.constants.ServerConstants.MAX_TIME; 13 | 14 | /** 15 | * @author fair 16 | * @version V1.0 17 | * @Package im.cave.ms.client 18 | * @date 1/20 10:50 19 | */ 20 | @Data 21 | @Entity 22 | @Table(name = "ht_reward") 23 | public class HotTimeReward { 24 | @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 25 | private int id; 26 | private int sort; //? 未知的 27 | private int type; //1 物品 3 MaplePoint 28 | private long receivedTime; 29 | private long expiredTime; 30 | private int itemId; 31 | private int quantity; 32 | private int meso; 33 | private int maplePoint; 34 | private int exp; 35 | private String msg; 36 | 37 | 38 | public void encode(OutPacket out) { 39 | out.writeInt(0); 40 | out.writeInt(getSort()); //11 12 13 14 41 | out.writeLong(getReceivedTime()); 42 | out.writeLong(getExpiredTime()); 43 | out.writeInt(getType()); 44 | out.writeInt(getItemId()); 45 | out.writeInt(getQuantity()); 46 | out.writeInt(0); 47 | out.writeLong(MAX_TIME); 48 | out.writeInt(0); 49 | out.writeInt(getMaplePoint()); 50 | out.writeZeroBytes(26); 51 | out.writeMapleAsciiString(getMsg()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/RecordManager.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.enums.RecordType; 5 | import im.cave.ms.tools.Util; 6 | import lombok.Getter; 7 | 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | /** 12 | * @author fair 13 | * @version V1.0 14 | * @Package im.cave.ms.client 15 | * @date 1/7 17:23 16 | */ 17 | @Getter 18 | public class RecordManager { 19 | private MapleCharacter chr; 20 | private Account account; 21 | 22 | public RecordManager(MapleCharacter chr) { 23 | this.chr = chr; 24 | } 25 | 26 | public RecordManager(Account account) { 27 | this.account = account; 28 | } 29 | 30 | public Set getRecords() { 31 | if (chr != null) { 32 | return chr.getRecords(); 33 | } else if (account != null) { 34 | return account.getRecords(); 35 | } 36 | return new HashSet<>(); 37 | } 38 | 39 | public void addRecord(Record record) { 40 | if (chr != null) { 41 | chr.getRecords().add(record); 42 | } else if (account != null) { 43 | account.getRecords().add(record); 44 | } 45 | } 46 | 47 | public Record getRecord(RecordType type, int key) { 48 | return Util.findWithPred(getRecords(), record -> record.getType() == type && record.getKey() == key); 49 | } 50 | 51 | public Record getRecord(RecordType type) { 52 | return Util.findWithPred(getRecords(), record -> record.getType() == type); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/KeyBind.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | 12 | /** 13 | * @author fair 14 | * @version V1.0 15 | * @Package im.cave.ms.client.character 16 | * @date 12/5 18:58 17 | */ 18 | @Data 19 | @Table(name = "key_binding") 20 | @Entity 21 | public class KeyBind { 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.IDENTITY) 24 | private int id; 25 | @Column(name = "`key`") 26 | private int key; 27 | private byte type; 28 | private int action; 29 | 30 | public KeyBind(int key, byte type, int action) { 31 | this.key = key; 32 | this.type = type; 33 | this.action = action; 34 | } 35 | 36 | public KeyBind() { 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/LinkSkill.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import javax.persistence.*; 8 | import java.util.Objects; 9 | 10 | @Getter 11 | @Setter 12 | @Table(name = "skill_link") 13 | @Entity 14 | public class LinkSkill { 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.IDENTITY) 17 | private long id; 18 | private int fromId; 19 | private int toId; 20 | private int skillId; 21 | private int level; 22 | private long time; 23 | 24 | @Override 25 | public boolean equals(Object o) { 26 | if (this == o) return true; 27 | if (o == null || getClass() != o.getClass()) return false; 28 | LinkSkill that = (LinkSkill) o; 29 | return fromId == that.fromId && skillId == that.skillId; 30 | } 31 | 32 | @Override 33 | public int hashCode() { 34 | return Objects.hash(fromId, skillId); 35 | } 36 | 37 | 38 | public void encode(OutPacket out) { 39 | out.writeInt(getFromId()); 40 | out.writeInt(getToId() == 0 ? getFromId() : getToId()); 41 | out.writeInt(getSkillId()); 42 | out.writeShort(getLevel()); 43 | out.writeLong(getTime()); 44 | out.writeInt(0); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/Macro.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character; 2 | 3 | 4 | import im.cave.ms.connection.db.InlinedIntArrayConverter; 5 | import im.cave.ms.connection.netty.OutPacket; 6 | 7 | import javax.persistence.Convert; 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.GenerationType; 11 | import javax.persistence.Id; 12 | import javax.persistence.Table; 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | 18 | @Entity 19 | @Table(name = "macro") 20 | public class Macro { 21 | 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.IDENTITY) 24 | private long id; 25 | 26 | private String name; 27 | private boolean muted; 28 | @Convert(converter = InlinedIntArrayConverter.class) 29 | private final List skills = new ArrayList<>(Arrays.asList(0, 0, 0)); 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public void setName(String name) { 36 | this.name = name; 37 | } 38 | 39 | public List getSkills() { 40 | return skills; 41 | } 42 | 43 | public long getId() { 44 | return id; 45 | } 46 | 47 | public void setId(long id) { 48 | this.id = id; 49 | } 50 | 51 | public boolean isMuted() { 52 | return muted; 53 | } 54 | 55 | public void setMuted(boolean muted) { 56 | this.muted = muted; 57 | } 58 | 59 | public void setSkillAtPos(int pos, int skillID) { 60 | if (pos >= 0 && pos < 3) { 61 | getSkills().set(pos, skillID); 62 | } 63 | } 64 | 65 | public void encode(OutPacket out) { 66 | out.writeMapleAsciiString(name); 67 | out.writeBool(isMuted()); 68 | for (int i : getSkills()) { 69 | out.writeInt(i); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/PortableChair.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import java.util.Set; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.client.character 12 | * @date 3/18 11:11 13 | */ 14 | @Getter 15 | @Setter 16 | public class PortableChair { 17 | int itemId; 18 | Set charId; 19 | boolean hasPortableMsg; 20 | String portableMsg; 21 | int arg1; 22 | int arg2; 23 | int arg3; 24 | int arg4; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/items/AuctionRecord.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.items; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | /** 8 | * @author fair 9 | * @version V1.0 10 | * @Package im.cave.ms.client.character.items 11 | * @date 2/5 10:44 12 | */ 13 | @Setter 14 | @Getter 15 | public class AuctionRecord { 16 | private int id; 17 | private int accId; 18 | private int worldId; 19 | private int sellerId; 20 | private String sellerName; 21 | private boolean meso; 22 | private long price; //单价 23 | private int count; 24 | private int buyerId; 25 | private String buyerName; 26 | private long startSaleTime; 27 | private long endSaleTime; 28 | private long saleTime; 29 | private Item item; 30 | 31 | 32 | public void encode(OutPacket out) { 33 | out.writeInt(getId()); 34 | out.writeInt(getWorldId()); 35 | out.writeInt(getAccId()); 36 | out.writeInt(getSellerId()); 37 | out.writeInt(5); 38 | out.writeInt(2); 39 | out.writeAsciiString(getSellerName(), 13); 40 | out.writeLong(0); //price 41 | out.writeLong(-1); //price 42 | out.writeLong(getPrice() * getCount()); 43 | out.writeLong(getPrice()); 44 | out.writeLong(getEndSaleTime()); 45 | out.writeInt(getBuyerId()); 46 | out.writeAsciiString(getBuyerName(), 13); 47 | out.writeInt(-1); 48 | out.writeLong(0); 49 | out.writeLong(getStartSaleTime()); 50 | out.writeLong(2000); //0 51 | out.writeInt(2); //1 52 | out.writeInt(1); // 0 53 | out.writeLong(getSaleTime()); 54 | out.writeInt(1); 55 | getItem().encode(out); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/items/ExceptionItem.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.items; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import javax.persistence.Table; 8 | 9 | /** 10 | * @author fair 11 | * @version V1.0 12 | * @Package im.cave.ms.client.character.items 13 | * @date 1/10 0:24 14 | */ 15 | @Entity 16 | @Table(name = "pet_exception_item") 17 | public class ExceptionItem { 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private long id; 21 | private long petId; 22 | private int itemId; 23 | 24 | public ExceptionItem(int itemId) { 25 | this.itemId = itemId; 26 | } 27 | 28 | public ExceptionItem() { 29 | } 30 | 31 | public int getItemId() { 32 | return itemId; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/items/InventoryOperation.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.items; 2 | 3 | import im.cave.ms.enums.InventoryOperationType; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | /** 8 | * @author fair 9 | * @version V1.0 10 | * @Package im.cave.ms.client.items 11 | * @date 12/29 16:37 12 | */ 13 | @Getter 14 | @Setter 15 | public class InventoryOperation { 16 | private InventoryOperationType type; 17 | private Item item; 18 | private short oldPos; 19 | private short newPos; 20 | private int bagPos = -1; 21 | 22 | public InventoryOperation(InventoryOperationType type, short oldPos, short newPos, Item item) { 23 | this.type = type; 24 | this.oldPos = oldPos; 25 | this.newPos = newPos; 26 | this.item = item; 27 | } 28 | 29 | public InventoryOperation(InventoryOperationType type) { 30 | this.type = type; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/items/ItemSkill.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.items; 2 | 3 | public class ItemSkill { 4 | private int skill; 5 | private byte slv; 6 | 7 | public ItemSkill(int skill, byte slv) { 8 | this.skill = skill; 9 | this.slv = slv; 10 | } 11 | 12 | public byte getSlv() { 13 | return slv; 14 | } 15 | 16 | public void setSlv(byte slv) { 17 | this.slv = slv; 18 | } 19 | 20 | public int getSkill() { 21 | return skill; 22 | } 23 | 24 | public void setSkill(int skill) { 25 | this.skill = skill; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/items/WishedItem.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.items; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | 12 | /** 13 | * @author fair 14 | * @version V1.0 15 | * @Package im.cave.ms.client.cashshop 16 | * @date 1/4 11:17 17 | */ 18 | @Entity 19 | @Setter 20 | @Getter 21 | @Table(name = "wished_item") 22 | public class WishedItem { 23 | @Id 24 | @GeneratedValue(strategy = GenerationType.IDENTITY) 25 | private int id; 26 | private int itemId; 27 | 28 | public WishedItem(int itemId) { 29 | this.itemId = itemId; 30 | } 31 | 32 | public WishedItem() { 33 | 34 | } 35 | 36 | @Override 37 | public boolean equals(Object o) { 38 | if (this == o) return true; 39 | if (o == null || getClass() != o.getClass()) return false; 40 | 41 | WishedItem item = (WishedItem) o; 42 | 43 | return itemId == item.itemId; 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | return itemId; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/job/adventurer/Pirate.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.job.adventurer; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.client.job.adventurer 7 | * @date 12/28 14:26 8 | */ 9 | public class Pirate { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/job/adventurer/Thief.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.job.adventurer; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.client.job.adventurer 7 | * @date 12/28 14:25 8 | */ 9 | public class Thief { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/legion/Legion.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.legion; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.client.character 9 | * @date 1/29 9:28 10 | */ 11 | public class Legion { 12 | private int level; 13 | private int count; 14 | 15 | 16 | public void encode(OutPacket out) { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/legion/LegionEntry.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.legion; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.client.character 7 | * @date 1/29 9:30 8 | */ 9 | public class LegionEntry { 10 | private int charId; 11 | private int job; 12 | private int level; 13 | private String name; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/skill/HitInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.skill; 2 | 3 | 4 | public class HitInfo { 5 | public int hpDamage; 6 | public int templateID; 7 | public int mobID; 8 | public int mpDamage; 9 | public int type = -1; 10 | public int skillID; 11 | public int otherUserID; 12 | public boolean isCrit; 13 | public int action; 14 | public boolean isGuard; 15 | public int hitAction; 16 | public int specialEffectSkill; // mask: 0x1 if true, 0x2 if custom skillID. Default is 33110000 (jaguar boost) 17 | public int curStanceSkill; 18 | public int reflectDamage; 19 | public int userSkillID; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/skill/MatrixSkill.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.skill; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import im.cave.ms.constants.ServerConstants; 5 | import im.cave.ms.enums.MatrixStateType; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | import javax.persistence.*; 10 | 11 | @Entity 12 | @Table(name = "matrix_skill") 13 | @Getter 14 | @Setter 15 | public class MatrixSkill { 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.IDENTITY) 18 | private long id; 19 | private int slot = -1; //未装备 20 | @Enumerated(EnumType.ORDINAL) 21 | @Column(name = "state") 22 | private MatrixStateType state; 23 | private int coreId; //核心ID 24 | private int skill1; 25 | private int skill2; 26 | private int skill3; 27 | private int level; 28 | private int masterLevel; 29 | private int experience; 30 | private long expirationDate = ServerConstants.MAX_TIME; 31 | 32 | 33 | public boolean isActive() { return state == MatrixStateType.ACTIVE; } 34 | 35 | 36 | public void encode(OutPacket out){ 37 | out.writeLong(getId()); 38 | out.writeInt(getCoreId()); 39 | out.writeInt(getLevel()); 40 | out.writeInt(getExperience()); 41 | out.writeInt(getState().getVal()); 42 | out.writeInt(getSkill1()); 43 | out.writeInt(getSkill2()); 44 | out.writeInt(getSkill3()); 45 | out.writeInt(getSlot()); 46 | out.writeLong(getExpirationDate()); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/skill/MatrixSlot.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.skill; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import javax.persistence.*; 8 | 9 | @Entity 10 | @Table(name = "matrix_slot") 11 | @Getter 12 | @Setter 13 | public class MatrixSlot { 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | private long id; 17 | private int slotId;//0-19 18 | private long equippedSkill = -1; 19 | private int enhanceLevel; 20 | 21 | 22 | public void encode(OutPacket out) { 23 | out.writeInt((int) getEquippedSkill()); 24 | out.writeInt(getSlotId()); 25 | out.writeInt(getEnhanceLevel()); 26 | out.write(0); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/skill/StopForceAtom.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.skill; 2 | 3 | 4 | import im.cave.ms.connection.netty.OutPacket; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class StopForceAtom { 10 | private int idx; 11 | private int count; 12 | private int weaponId; 13 | private List angleInfo = new ArrayList<>(); 14 | 15 | public void encode(OutPacket out) { 16 | out.writeInt(getIdx()); 17 | out.writeInt(getCount()); 18 | out.writeInt(getWeaponId()); 19 | out.writeInt(getAngleInfo().size()); 20 | for (int i : getAngleInfo()) { 21 | out.writeInt(i); 22 | } 23 | } 24 | 25 | public int getIdx() { 26 | return idx; 27 | } 28 | 29 | public void setIdx(int idx) { 30 | this.idx = idx; 31 | } 32 | 33 | public int getCount() { 34 | return count; 35 | } 36 | 37 | public void setCount(int count) { 38 | this.count = count; 39 | } 40 | 41 | public int getWeaponId() { 42 | return weaponId; 43 | } 44 | 45 | public void setWeaponId(int weaponId) { 46 | this.weaponId = weaponId; 47 | } 48 | 49 | public List getAngleInfo() { 50 | return angleInfo; 51 | } 52 | 53 | public void setAngleInfo(List angleInfo) { 54 | this.angleInfo = angleInfo; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/character/temp/TwoStateTemporaryStat.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.character.temp; 2 | 3 | 4 | public class TwoStateTemporaryStat extends TemporaryStatBase { 5 | 6 | public TwoStateTemporaryStat(boolean dynamicTermSet) { 7 | super(dynamicTermSet); 8 | } 9 | 10 | @Override 11 | public int getMaxValue() { 12 | return 0; 13 | } 14 | 15 | @Override 16 | public boolean isActive() { 17 | return getNOption() != 0; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/FieldAttackObj.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.field.obj.MapleMapObj; 5 | import im.cave.ms.connection.netty.OutPacket; 6 | import im.cave.ms.connection.packet.FieldAttackObjPacket; 7 | import im.cave.ms.tools.Position; 8 | 9 | public class FieldAttackObj extends MapleMapObj { 10 | 11 | private int ownerID; 12 | private int reserveID; 13 | 14 | public FieldAttackObj(int templateId) { 15 | super(templateId); 16 | } 17 | 18 | public FieldAttackObj(int templateId, int ownerID, Position position, boolean flip) { 19 | super(templateId); 20 | this.ownerID = ownerID; 21 | setPosition(position); 22 | setFlip(flip); 23 | } 24 | 25 | public int getOwnerID() { 26 | return ownerID; 27 | } 28 | 29 | public void setOwnerID(int ownerID) { 30 | this.ownerID = ownerID; 31 | } 32 | 33 | public int getReserveID() { 34 | return reserveID; 35 | } 36 | 37 | public void setReserveID(int reserveID) { 38 | this.reserveID = reserveID; 39 | } 40 | 41 | 42 | public void encode(OutPacket out) { 43 | out.writeInt(getObjectId()); 44 | out.writeInt(getTemplateId()); 45 | out.writeInt(getOwnerID()); 46 | out.writeInt(getReserveID()); 47 | out.write(0); 48 | out.writePositionInt(getPosition()); 49 | out.writeBool(isFlip()); 50 | } 51 | 52 | 53 | @Override 54 | public void sendLeavePacket(MapleCharacter chr) { 55 | chr.announce(FieldAttackObjPacket.objRemoveList(getTemplateId(), getObjectId())); 56 | } 57 | 58 | @Override 59 | public void sendSpawnPacket(MapleCharacter chr) { 60 | chr.announce(FieldAttackObjPacket.objCreate(this)); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/Movement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.field.obj.MapleMapObj; 5 | import im.cave.ms.connection.netty.OutPacket; 6 | import im.cave.ms.tools.Position; 7 | 8 | 9 | public interface Movement { 10 | void encode(OutPacket out); 11 | 12 | Position getPosition(); 13 | 14 | byte getCommand(); 15 | 16 | byte getMoveAction(); 17 | 18 | byte getForcedStop(); 19 | 20 | byte getStat(); 21 | 22 | short getFh(); 23 | 24 | short getFootStart(); 25 | 26 | short getDuration(); 27 | 28 | Position getVPosition(); 29 | 30 | Position getOffset(); 31 | 32 | void applyTo(MapleCharacter chr); 33 | 34 | void applyTo(MapleMapObj obj); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/MovementAction.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.field.obj.MapleMapObj; 5 | import im.cave.ms.connection.netty.InPacket; 6 | import im.cave.ms.connection.netty.OutPacket; 7 | import im.cave.ms.tools.Position; 8 | 9 | 10 | 11 | public class MovementAction extends MovementBase { 12 | public MovementAction(InPacket in, byte command) { 13 | super(); 14 | this.command = command; 15 | this.position = new Position(0, 0); 16 | 17 | moveAction = in.readByte(); 18 | elapse = in.readShort(); 19 | forcedStop = in.readByte(); 20 | } 21 | 22 | @Override 23 | public void encode(OutPacket out) { 24 | out.write(getCommand()); 25 | out.write(getMoveAction()); 26 | out.writeShort(getDuration()); 27 | out.write(getForcedStop()); 28 | } 29 | 30 | @Override 31 | public void applyTo(MapleCharacter chr) { 32 | chr.setMoveAction(moveAction); 33 | } 34 | 35 | @Override 36 | public void applyTo(MapleMapObj life) { 37 | life.setMoveAction(moveAction); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/MovementAngle.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.client.field.obj.MapleMapObj; 6 | import im.cave.ms.connection.netty.InPacket; 7 | import im.cave.ms.connection.netty.OutPacket; 8 | import im.cave.ms.tools.Position; 9 | 10 | 11 | public class MovementAngle extends MovementBase { 12 | public MovementAngle(InPacket in, byte command) { 13 | super(); 14 | this.command = command; 15 | 16 | short x = in.readShort(); 17 | short y = in.readShort(); 18 | position = new Position(x, y); 19 | 20 | short xv = in.readShort(); 21 | short xy = in.readShort(); 22 | vPosition = new Position(xv, xy); 23 | 24 | fh = in.readShort(); 25 | 26 | moveAction = in.readByte(); 27 | elapse = in.readShort(); 28 | forcedStop = in.readByte(); 29 | } 30 | 31 | @Override 32 | public void encode(OutPacket out) { 33 | out.write(getCommand()); 34 | out.writePosition(getPosition()); 35 | out.writePosition(getVPosition()); 36 | out.writeShort(getFh()); 37 | out.write(getMoveAction()); 38 | out.writeShort(getDuration()); 39 | out.write(getForcedStop()); 40 | } 41 | 42 | @Override 43 | public void applyTo(MapleCharacter chr) { 44 | chr.setPosition(getPosition()); 45 | chr.setFoothold(getFh()); 46 | chr.setMoveAction(getMoveAction()); 47 | } 48 | 49 | @Override 50 | public void applyTo(MapleMapObj obj) { 51 | obj.setPosition(getPosition()); 52 | obj.setVPosition(getVPosition()); 53 | obj.setFh(getFh()); 54 | obj.setMoveAction(getMoveAction()); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/MovementFlyingBlock.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.client.field.obj.MapleMapObj; 6 | import im.cave.ms.connection.netty.InPacket; 7 | import im.cave.ms.connection.netty.OutPacket; 8 | import im.cave.ms.tools.Position; 9 | 10 | public class MovementFlyingBlock extends MovementBase { 11 | public MovementFlyingBlock(InPacket in, byte command) { 12 | super(); 13 | this.command = command; 14 | 15 | short x = in.readShort(); 16 | short y = in.readShort(); 17 | position = new Position(x, y); 18 | 19 | short vx = in.readShort(); 20 | short vy = in.readShort(); 21 | vPosition = new Position(vx, vy); 22 | 23 | moveAction = in.readByte(); 24 | elapse = in.readShort(); 25 | forcedStop = in.readByte(); 26 | } 27 | 28 | @Override 29 | public void encode(OutPacket out) { 30 | out.write(getCommand()); 31 | out.writePosition(getPosition()); 32 | out.writePosition(getVPosition()); 33 | out.write(getMoveAction()); 34 | out.writeShort(getDuration()); 35 | out.write(getForcedStop()); 36 | } 37 | 38 | @Override 39 | public void applyTo(MapleCharacter chr) { 40 | chr.setPosition(getPosition()); 41 | chr.setMoveAction(getMoveAction()); 42 | } 43 | 44 | @Override 45 | public void applyTo(MapleMapObj life) { 46 | life.setPosition(getPosition()); 47 | life.setVPosition(getVPosition()); 48 | life.setMoveAction(getMoveAction()); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/MovementStartFallDown.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.field.obj.MapleMapObj; 5 | import im.cave.ms.connection.netty.InPacket; 6 | import im.cave.ms.connection.netty.OutPacket; 7 | import im.cave.ms.tools.Position; 8 | 9 | 10 | 11 | public class MovementStartFallDown extends MovementBase { 12 | public MovementStartFallDown(InPacket in, byte command) { 13 | super(); 14 | this.command = command; 15 | this.position = new Position(0, 0); 16 | 17 | short xv = in.readShort(); 18 | short xy = in.readShort(); 19 | vPosition = new Position(xv, xy); 20 | 21 | // I'm not sure about this, it' needs testing. <- mushy 22 | // Should be fallStart (foothold fall start)? 23 | footStart = in.readShort(); 24 | 25 | moveAction = in.readByte(); 26 | elapse = in.readShort(); 27 | forcedStop = in.readByte(); 28 | } 29 | 30 | @Override 31 | public void encode(OutPacket out) { 32 | out.write(getCommand()); 33 | out.writePosition(getVPosition()); 34 | out.writeShort(getFootStart()); 35 | out.write(getMoveAction()); 36 | out.writeShort(getDuration()); 37 | out.write(getForcedStop()); 38 | } 39 | 40 | @Override 41 | public void applyTo(MapleCharacter chr) { 42 | chr.setPosition(getPosition()); 43 | chr.setFoothold(getFh()); 44 | chr.setMoveAction(getMoveAction()); 45 | } 46 | 47 | @Override 48 | public void applyTo(MapleMapObj life) { 49 | life.setPosition(getPosition()); 50 | life.setVPosition(getVPosition()); 51 | life.setFh(getFh()); 52 | life.setMoveAction(getMoveAction()); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/MovementStatChange.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.client.field.obj.MapleMapObj; 6 | import im.cave.ms.connection.netty.InPacket; 7 | import im.cave.ms.connection.netty.OutPacket; 8 | import im.cave.ms.tools.Position; 9 | 10 | 11 | public class MovementStatChange extends MovementBase { 12 | public MovementStatChange(InPacket in, byte command) { 13 | super(); 14 | this.command = command; 15 | this.position = new Position(0, 0); 16 | 17 | this.stat = in.readByte(); 18 | } 19 | 20 | @Override 21 | public void encode(OutPacket out) { 22 | out.write(getCommand()); 23 | out.write(getStat()); 24 | } 25 | 26 | @Override 27 | public void applyTo(MapleCharacter chr) { 28 | 29 | } 30 | 31 | @Override 32 | public void applyTo(MapleMapObj life) { 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/MovementTeleport.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.client.field.obj.MapleMapObj; 6 | import im.cave.ms.connection.netty.InPacket; 7 | import im.cave.ms.connection.netty.OutPacket; 8 | import im.cave.ms.tools.Position; 9 | 10 | 11 | 12 | public class MovementTeleport extends MovementBase { 13 | public MovementTeleport(InPacket in, byte command) { 14 | super(); 15 | this.command = command; 16 | 17 | short x = in.readShort(); 18 | short y = in.readShort(); 19 | position = new Position(x, y); 20 | 21 | fh = in.readShort(); 22 | in.readInt(); // unk 23 | moveAction = in.readByte(); 24 | elapse = in.readShort(); 25 | forcedStop = in.readByte(); 26 | } 27 | 28 | @Override 29 | public void encode(OutPacket out) { 30 | out.write(getCommand()); 31 | out.writePosition(getPosition()); 32 | out.writeShort(getFh()); 33 | out.write(getMoveAction()); 34 | out.writeShort(getDuration()); 35 | out.write(getForcedStop()); 36 | } 37 | 38 | @Override 39 | public void applyTo(MapleCharacter chr) { 40 | chr.setPosition(getPosition()); 41 | chr.setFoothold(getFh()); 42 | chr.setMoveAction(getMoveAction()); 43 | } 44 | 45 | @Override 46 | public void applyTo(MapleMapObj life) { 47 | life.setPosition(getPosition()); 48 | life.setFh(getFh()); 49 | life.setMoveAction(getMoveAction()); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/movement/MovementUNK.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.movement; 2 | 3 | 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.client.field.obj.MapleMapObj; 6 | import im.cave.ms.connection.netty.InPacket; 7 | import im.cave.ms.connection.netty.OutPacket; 8 | import im.cave.ms.tools.Position; 9 | 10 | 11 | 12 | /** 13 | * Created by MechAviv on 2/2/2019. 14 | */ 15 | public class MovementUNK extends MovementBase { 16 | public MovementUNK(InPacket in, byte command) { 17 | super(); 18 | this.command = command; 19 | this.position = new Position(0, 0); 20 | 21 | short xv = in.readShort(); 22 | short xy = in.readShort(); 23 | vPosition = new Position(xv, xy); 24 | 25 | moveAction = in.readByte(); 26 | elapse = in.readShort(); 27 | forcedStop = in.readByte(); 28 | } 29 | 30 | @Override 31 | public void encode(OutPacket out) { 32 | out.write(getCommand()); 33 | out.writePosition(getVPosition()); 34 | out.write(getMoveAction()); 35 | out.writeShort(getDuration()); 36 | out.write(getForcedStop()); 37 | } 38 | 39 | @Override 40 | public void applyTo(MapleCharacter chr) { 41 | chr.setPosition(getPosition()); 42 | chr.setMoveAction(getMoveAction()); 43 | } 44 | 45 | @Override 46 | public void applyTo(MapleMapObj life) { 47 | life.setPosition(getPosition()); 48 | life.setVPosition(getVPosition()); 49 | life.setMoveAction(getMoveAction()); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/Android.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.connection.netty.OutPacket; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | import javax.persistence.Transient; 12 | 13 | /** 14 | * @author fair 15 | * @version V1.0 16 | * @Package im.cave.ms.client.field.obj 17 | * @date 1/1 16:54 18 | */ 19 | @Getter 20 | @Setter 21 | @Entity 22 | @Table(name = "android") 23 | public class Android extends MapleMapObj { 24 | @Id 25 | private long itemId; 26 | @Transient 27 | private MapleCharacter owner; 28 | private short skin; 29 | private short hair; 30 | private short face; 31 | private String name; 32 | private int type; 33 | 34 | public void encode(OutPacket out) { 35 | out.write(getType()); 36 | out.writePosition(getPosition()); 37 | out.write(getMoveAction()); 38 | out.writeShort(getFh()); 39 | out.writeInt(0); 40 | encodeAndroidInfo(out); 41 | out.writeZeroBytes(68); //装备 42 | } 43 | 44 | 45 | public void encodeAndroidInfo(OutPacket out) { 46 | out.writeShort(getSkin() >= 2000 ? getSkin() - 2000 : getSkin()); 47 | out.writeShort(getHair() - 30000); 48 | out.writeShort(getFace() - 20000); 49 | out.writeMapleAsciiString(getName()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/Pet.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj; 2 | 3 | import im.cave.ms.client.character.items.PetItem; 4 | import im.cave.ms.connection.netty.OutPacket; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.client.field.obj 12 | * @date 1/1 21:48 13 | */ 14 | @Getter 15 | @Setter 16 | public class Pet extends MapleMapObj { 17 | private final int ownerId; 18 | private int id; 19 | private int idx; 20 | private String name; 21 | private long petLockerSN; 22 | private int hue = -1; 23 | private short giantRate = 100; 24 | private boolean transformed; 25 | private boolean reinforced; 26 | private PetItem petItem; 27 | 28 | public Pet(int templateId, int ownerId) { 29 | super(templateId); 30 | this.ownerId = ownerId; 31 | } 32 | 33 | public void encode(OutPacket out) { 34 | out.writeInt(getTemplateId()); 35 | out.writeMapleAsciiString(getName()); 36 | out.writeLong(getPetItem().getCashItemSerialNumber()); 37 | out.writePosition(getPosition()); 38 | out.write(getMoveAction()); 39 | out.writeShort(getFh()); 40 | out.writeInt(getHue()); 41 | out.writeShort(getGiantRate()); 42 | out.writeInt(0); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/Reactor.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | /** 7 | * @author fair 8 | * @version V1.0 9 | * @Package im.cave.ms.client.field.obj 10 | * @date 1/4 16:34 11 | */ 12 | @Getter 13 | @Setter 14 | public class Reactor extends MapleMapObj { 15 | 16 | private byte state; 17 | private String name = ""; 18 | private int ownerId; 19 | private int properEventIdx; 20 | private int reactorTime; 21 | private boolean phantomForest; 22 | private int hitCount; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/mob/EscortDest.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj.mob; 2 | 3 | import im.cave.ms.tools.Position; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.client.field.obj.mob 9 | * @date 3/17 9:22 10 | */ 11 | public class EscortDest { 12 | private final Position destPos; 13 | private final int attr; 14 | private final int mass; 15 | private final int stopDuration; 16 | 17 | public EscortDest(int destPosX, int destPosY, int attr, int mass, int stopDuration) { 18 | this.destPos = new Position(destPosX, destPosY); 19 | this.attr = attr; 20 | this.mass = mass; 21 | this.stopDuration = stopDuration; 22 | } 23 | 24 | public Position getDestPos() { 25 | return destPos; 26 | } 27 | 28 | public int getAttr() { 29 | return attr; 30 | } 31 | 32 | public int getMass() { 33 | return mass; 34 | } 35 | 36 | public int getStopDuration() { 37 | return stopDuration; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/mob/MobGen.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj.mob; 2 | 3 | import im.cave.ms.client.field.MapleMap; 4 | import im.cave.ms.client.field.obj.MapleMapObj; 5 | import im.cave.ms.tools.Position; 6 | 7 | 8 | public class MobGen extends MapleMapObj { 9 | 10 | private Mob mob; 11 | private long nextPossibleSpawnTime = Long.MIN_VALUE; 12 | private boolean hasSpawned; 13 | 14 | public MobGen(int templateId) { 15 | super(templateId); 16 | } 17 | 18 | public Mob getMob() { 19 | return mob; 20 | } 21 | 22 | public void setMob(Mob mob) { 23 | this.mob = mob; 24 | this.setPosition(mob.getHomePosition().deepCopy()); 25 | } 26 | 27 | public long getNextPossibleSpawnTime() { 28 | return nextPossibleSpawnTime; 29 | } 30 | 31 | public void setNextPossibleSpawnTime(long nextPossibleSpawnTime) { 32 | this.nextPossibleSpawnTime = nextPossibleSpawnTime; 33 | } 34 | 35 | public boolean hasSpawned() { 36 | return hasSpawned; 37 | } 38 | 39 | public void setHasSpawned(boolean hasSpawned) { 40 | this.hasSpawned = hasSpawned; 41 | } 42 | 43 | public boolean canSpawnOnField(MapleMap map) { 44 | 45 | int currentMobs = map.getMobs().size(); 46 | return currentMobs < map.getMobCapacity() && 47 | getNextPossibleSpawnTime() < System.currentTimeMillis() && 48 | (getMob().getMobTime() != -1 || !hasSpawned()); 49 | } 50 | 51 | public void spawnMob(MapleMap map) { 52 | Mob mob = getMob().deepCopy(); 53 | Position pos = mob.getHomePosition(); 54 | mob.setPosition(pos.deepCopy()); 55 | mob.setHomePosition(pos.deepCopy()); 56 | map.spawnObj(mob, null); 57 | setNextPossibleSpawnTime(System.currentTimeMillis() + (getMob().getMobTime() * 1000)); 58 | setHasSpawned(true); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/mob/MobSkill.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj.mob; 2 | 3 | import im.cave.ms.client.character.skill.MobSkillInfo; 4 | import im.cave.ms.provider.data.SkillData; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.client.field.obj.mob 12 | * @date 2/2 16:54 13 | */ 14 | @Getter 15 | @Setter 16 | public class MobSkill { 17 | private int skillSN; 18 | private byte action; 19 | private int level; 20 | private int effectAfter; 21 | private int skillAfter; 22 | private byte priority; 23 | private boolean firstAttack; 24 | private boolean onlyFsm; 25 | private boolean onlyOtherSkill; 26 | private int skillForbid; 27 | private int afterDelay; 28 | private int fixDamR; 29 | private boolean doFirst; 30 | private int preSkillIndex; 31 | private int preSkillCount; 32 | private String info; 33 | private String text; 34 | private boolean afterDead; 35 | private int afterAttack = -1; 36 | private int afterAttackCount; 37 | private int castTime; 38 | private int coolTime; 39 | private int delay; 40 | private int useLimit; 41 | private String speak; 42 | private int skillID; 43 | 44 | 45 | public void handleEffect(Mob mob) { 46 | MobTemporaryStat mts = mob.getTemporaryStat(); 47 | short skill = (short) getSkillID(); 48 | short level = (short) getLevel(); 49 | // MobSkillInfo msi = SkillData.getMobSkillInfoByIdAndLevel(skill, level); 50 | // MobSkillID msID = MobSkillID.getMobSkillIDByVal(skill); 51 | // Field field = mob.getField(); 52 | // Option o = new Option(skill); 53 | // o.slv = level; 54 | // o.tOption = msi.getSkillStatIntValue(time); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/mob/MobSkillAttackInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj.mob; 2 | 3 | 4 | import im.cave.ms.tools.Position; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class MobSkillAttackInfo { 10 | public byte actionAndDirMask; 11 | public byte action; 12 | public long targetInfo; 13 | public short skillID; 14 | public List multiTargetForBalls = new ArrayList<>(); 15 | public List randTimeForAreaAttacks = new ArrayList<>(); 16 | public List unks = new ArrayList<>(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/npc/shop/BuyLimitInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj.npc.shop; 2 | 3 | 4 | import im.cave.ms.connection.netty.OutPacket; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | 10 | public class BuyLimitInfo { 11 | 12 | private int type; 13 | private Set dates = new HashSet<>(); 14 | 15 | public void encode(OutPacket out) { 16 | out.write(getType()); 17 | if (getType() == 1 || getType() == 3 || getType() == 4) { 18 | out.writeInt(getDates().size()); 19 | for (Long ft : getDates()) { 20 | out.writeLong(ft); 21 | } 22 | } 23 | } 24 | 25 | public int getType() { 26 | return type; 27 | } 28 | 29 | public void setType(int type) { 30 | this.type = type; 31 | } 32 | 33 | public Set getDates() { 34 | return dates; 35 | } 36 | 37 | public void addDate(Long fileTime) { 38 | getDates().add(fileTime); 39 | } 40 | 41 | public void removeDate(Long fileTime) { 42 | getDates().remove(fileTime); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obj/npc/shop/NpcShop.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obj.npc.shop; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import im.cave.ms.tools.DateUtil; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.ListIterator; 11 | 12 | /** 13 | * @author fair 14 | * @version V1.0 15 | * @Package im.cave.ms.client.field.obj 16 | * @date 12/27 0:22 17 | */ 18 | @Getter 19 | @Setter 20 | public class NpcShop { 21 | private int shopId; 22 | private int selectNpcItemId; 23 | private int npcTemplateId; 24 | private int starCoin; 25 | private int shopVerNo; 26 | private List items = new ArrayList<>(); 27 | 28 | public List getItems() { 29 | return items; 30 | } 31 | 32 | public void setItems(List items) { 33 | this.items = items; 34 | } 35 | 36 | public void encode(OutPacket out, List repurchaseItems) { 37 | out.writeZeroBytes(20); 38 | out.writeInt(DateUtil.getTime()); 39 | out.writeBool(false); 40 | out.writeShort(items.size() + repurchaseItems.size()); 41 | items.forEach(npcShopItem -> npcShopItem.encode(out)); 42 | ListIterator itemListIterator; 43 | for (itemListIterator = repurchaseItems.listIterator(); itemListIterator.hasNext(); ) { 44 | itemListIterator.next(); 45 | } 46 | while (itemListIterator.hasPrevious()) { 47 | NpcShopItem shopItem = itemListIterator.previous(); 48 | shopItem.encode(out); 49 | } 50 | } 51 | 52 | public NpcShopItem getItemByIndex(int idx) { 53 | NpcShopItem item = null; 54 | if (idx >= 0 && idx < getItems().size()) { 55 | item = getItems().get(idx); 56 | } 57 | return item; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/field/obstacleatom/ObstacleRadianInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.field.obstacleatom; 2 | 3 | 4 | import im.cave.ms.connection.netty.OutPacket; 5 | 6 | public class ObstacleRadianInfo { 7 | 8 | private int effect; 9 | private int minRad; // guess 10 | private int maxRad; // guess 11 | private int startX; 12 | private int height; 13 | 14 | public ObstacleRadianInfo() { 15 | } 16 | 17 | public ObstacleRadianInfo(int effect, int minRad, int maxRad, int startX, int height) { 18 | this.effect = effect; 19 | this.minRad = minRad; 20 | this.maxRad = maxRad; 21 | this.startX = startX; 22 | this.height = height; 23 | } 24 | 25 | public void encode(OutPacket outPacket) { 26 | outPacket.writeInt(getEffect()); 27 | outPacket.writeInt(getMinRad()); 28 | outPacket.writeInt(getMaxRad()); 29 | outPacket.writeInt(getStartX()); 30 | outPacket.writeInt(getHeight()); 31 | } 32 | 33 | public int getEffect() { 34 | return effect; 35 | } 36 | 37 | public void setEffect(int effect) { 38 | this.effect = effect; 39 | } 40 | 41 | public int getMinRad() { 42 | return minRad; 43 | } 44 | 45 | public void setMinRad(int minRad) { 46 | this.minRad = minRad; 47 | } 48 | 49 | public int getMaxRad() { 50 | return maxRad; 51 | } 52 | 53 | public void setMaxRad(int maxRad) { 54 | this.maxRad = maxRad; 55 | } 56 | 57 | public int getStartX() { 58 | return startX; 59 | } 60 | 61 | public void setStartX(int startX) { 62 | this.startX = startX; 63 | } 64 | 65 | public int getHeight() { 66 | return height; 67 | } 68 | 69 | public void setHeight(int height) { 70 | this.height = height; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/multiplayer/guilds/GuildGrade.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.multiplayer.guilds; 2 | 3 | import im.cave.ms.enums.GuildRight; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import javax.persistence.Column; 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.GenerationType; 11 | import javax.persistence.Id; 12 | import javax.persistence.Table; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * @author fair 18 | * @version V1.0 19 | * @Package im.cave.ms.client.multiplayer.guilds 20 | * @date 2/3 9:10 21 | */ 22 | @Entity 23 | @Table(name = "guild_grade") 24 | @Getter 25 | @Setter 26 | public class GuildGrade { 27 | @Id 28 | @GeneratedValue(strategy = GenerationType.IDENTITY) 29 | private int id; 30 | private int grade; 31 | private String name; 32 | private int right; 33 | 34 | public GuildGrade(int grade, String name, GuildRight... rights) { 35 | this.grade = grade; 36 | this.name = name; 37 | for (GuildRight right : rights) { 38 | this.right = this.right | right.getVal(); 39 | } 40 | } 41 | 42 | public GuildGrade() { 43 | 44 | } 45 | 46 | public static List getDefault() { 47 | List grades = new ArrayList<>(); 48 | grades.add(new GuildGrade(1, "族长", GuildRight.ALL)); 49 | grades.add(new GuildGrade(2, "副族长", GuildRight.INVITE, GuildRight.VERIFY_APPLY)); 50 | grades.add(new GuildGrade(3, "成员", GuildRight.NULL)); 51 | grades.add(new GuildGrade(4, "成员", GuildRight.NULL)); 52 | grades.add(new GuildGrade(5, "成员", GuildRight.NULL)); 53 | return grades; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/multiplayer/guilds/GuildSkill.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.multiplayer.guilds; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.GenerationType; 10 | import javax.persistence.Id; 11 | import javax.persistence.Table; 12 | 13 | /** 14 | * @author fair 15 | * @version V1.0 16 | * @Package im.cave.ms.client.multiplayer.guilds 17 | * @date 2/3 14:39 18 | */ 19 | @Entity 20 | @Table(name = "guild_skill") 21 | @Getter 22 | @Setter 23 | public class GuildSkill { 24 | @Id 25 | @GeneratedValue(strategy = GenerationType.IDENTITY) 26 | private int id; 27 | private int skillId; 28 | private byte level; 29 | private long expireDate; 30 | private String buyCharName; 31 | private String extendCharName; 32 | 33 | 34 | public void encode(OutPacket out) { 35 | out.writeShort(getLevel()); 36 | out.writeLong(getExpireDate()); 37 | out.writeMapleAsciiString(getBuyCharName()); 38 | out.writeMapleAsciiString(getExtendCharName()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/multiplayer/miniroom/ChatRoom.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.multiplayer.miniroom; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.connection.netty.OutPacket; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.concurrent.atomic.AtomicInteger; 9 | 10 | /** 11 | * @author fair 12 | * @version V1.0 13 | * @Package im.cave.ms.client.social.miniroom 14 | * @date 1/12 20:43 15 | */ 16 | public class ChatRoom implements MiniRoom { 17 | public static final AtomicInteger counter = new AtomicInteger(1); 18 | private int chatRoomId; 19 | private final List chars = new ArrayList<>(6); 20 | 21 | public ChatRoom(MapleCharacter chr) { 22 | chatRoomId = counter.getAndIncrement(); 23 | chars.add(chr); 24 | } 25 | 26 | public void broadcast(OutPacket chatRoomInviteTip, MapleCharacter player) { 27 | for (MapleCharacter chr : chars) { 28 | if (player != chr) { 29 | chr.announce(chatRoomInviteTip); 30 | } 31 | } 32 | } 33 | 34 | public int getChatRoomId() { 35 | return chatRoomId; 36 | } 37 | 38 | public void setChatRoomId(int chatRoomId) { 39 | this.chatRoomId = chatRoomId; 40 | } 41 | 42 | @Override 43 | public void close() { 44 | 45 | } 46 | 47 | @Override 48 | public void invite(MapleCharacter inviter, MapleCharacter invitee) { 49 | 50 | } 51 | 52 | @Override 53 | public void invite(MapleCharacter invitee) { 54 | 55 | } 56 | 57 | @Override 58 | public void exit(MapleCharacter chr) { 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/multiplayer/miniroom/MiniRoom.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.multiplayer.miniroom; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.client.miniroom 9 | * @date 12/29 14:47 10 | */ 11 | public interface MiniRoom { 12 | //关闭 13 | void close(); 14 | 15 | //邀请 16 | void invite(MapleCharacter inviter, MapleCharacter invitee); 17 | 18 | //邀请 19 | void invite(MapleCharacter invitee); 20 | 21 | //退出 22 | void exit(MapleCharacter chr); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/multiplayer/miniroom/RPSRoom.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.multiplayer.miniroom; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | /* 6 | 剪刀石头布 7 | */ 8 | public class RPSRoom implements MiniRoom { 9 | @Override 10 | public void close() { 11 | 12 | } 13 | 14 | @Override 15 | public void invite(MapleCharacter inviter, MapleCharacter invitee) { 16 | 17 | } 18 | 19 | @Override 20 | public void invite(MapleCharacter invitee) { 21 | 22 | } 23 | 24 | @Override 25 | public void exit(MapleCharacter chr) { 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/multiplayer/party/TownPortal.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.multiplayer.party; 2 | 3 | 4 | import im.cave.ms.connection.netty.OutPacket; 5 | import im.cave.ms.tools.Position; 6 | 7 | import static im.cave.ms.constants.GameConstants.NO_MAP_ID; 8 | 9 | public class TownPortal { 10 | 11 | private int townID = NO_MAP_ID; 12 | private int fieldID = NO_MAP_ID; 13 | private int skillID; 14 | private Position fieldPortal; 15 | 16 | public int getTownID() { 17 | return townID; 18 | } 19 | 20 | public void setTownID(int townID) { 21 | this.townID = townID; 22 | } 23 | 24 | public int getFieldID() { 25 | return fieldID; 26 | } 27 | 28 | public void setFieldID(int fieldID) { 29 | this.fieldID = fieldID; 30 | } 31 | 32 | public int getSkillID() { 33 | return skillID; 34 | } 35 | 36 | public void setSkillID(int skillID) { 37 | this.skillID = skillID; 38 | } 39 | 40 | public Position getFieldPortal() { 41 | return fieldPortal; 42 | } 43 | 44 | public void setFieldPortal(Position fieldPortal) { 45 | this.fieldPortal = fieldPortal; 46 | } 47 | 48 | public void encode(OutPacket out) { 49 | out.writeInt(getTownID()); 50 | out.writeInt(getFieldID()); 51 | out.writeInt(getSkillID()); 52 | out.writePosition(getFieldPortal()); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/progress/QuestProgressItemRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.progress; 2 | 3 | 4 | import im.cave.ms.client.character.MapleCharacter; 5 | 6 | import javax.persistence.Column; 7 | import javax.persistence.DiscriminatorValue; 8 | import javax.persistence.Entity; 9 | 10 | 11 | @Entity 12 | @DiscriminatorValue("item") 13 | public class QuestProgressItemRequirement extends QuestProgressRequirement { 14 | 15 | 16 | @Column(name = "unitID") 17 | private int itemID; 18 | @Column(name = "requiredCount") 19 | private int requiredCount; 20 | 21 | public QuestProgressItemRequirement() { 22 | } 23 | 24 | public int getItemID() { 25 | return itemID; 26 | } 27 | 28 | public void setItemID(int itemID) { 29 | this.itemID = itemID; 30 | } 31 | 32 | public int getRequiredCount() { 33 | return requiredCount; 34 | } 35 | 36 | public void setRequiredCount(int requiredCount) { 37 | this.requiredCount = requiredCount; 38 | } 39 | 40 | @Override 41 | public boolean isComplete(MapleCharacter chr) { 42 | return chr.hasItemCount(getItemID(), getRequiredCount()); 43 | } 44 | 45 | public QuestProgressRequirement deepCopy() { 46 | QuestProgressItemRequirement qpir = new QuestProgressItemRequirement(); 47 | qpir.setItemID(getItemID()); 48 | qpir.setRequiredCount(getRequiredCount()); 49 | qpir.setOrder(getOrder()); 50 | return qpir; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/progress/QuestProgressLevelRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.progress; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.DiscriminatorValue; 7 | import javax.persistence.Entity; 8 | 9 | 10 | @Entity 11 | @DiscriminatorValue("level") 12 | public class QuestProgressLevelRequirement extends QuestProgressRequirement { 13 | 14 | @Column(name = "requiredCount") 15 | private int level; 16 | 17 | public QuestProgressLevelRequirement() { 18 | } 19 | 20 | public QuestProgressLevelRequirement(int level) { 21 | this.level = level; 22 | } 23 | 24 | @Override 25 | public boolean isComplete(MapleCharacter chr) { 26 | return chr.getLevel() >= getLevel(); 27 | } 28 | 29 | public QuestProgressRequirement deepCopy() { 30 | QuestProgressLevelRequirement qplr = new QuestProgressLevelRequirement(); 31 | qplr.setLevel(getLevel()); 32 | qplr.setOrder(getOrder()); 33 | return qplr; 34 | } 35 | 36 | public int getLevel() { 37 | return level; 38 | } 39 | 40 | public void setLevel(int level) { 41 | this.level = level; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/progress/QuestProgressMoneyRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.progress; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.DiscriminatorValue; 7 | import javax.persistence.Entity; 8 | 9 | 10 | @Entity 11 | @DiscriminatorValue("money") 12 | public class QuestProgressMoneyRequirement extends QuestProgressRequirement { 13 | 14 | @Column(name = "requiredCount") 15 | private int money; 16 | 17 | public QuestProgressMoneyRequirement() { 18 | } 19 | 20 | public QuestProgressMoneyRequirement(int money) { 21 | this.money = money; 22 | } 23 | 24 | @Override 25 | public boolean isComplete(MapleCharacter chr) { 26 | return chr.getMeso() >= getMoney(); 27 | } 28 | 29 | public QuestProgressRequirement deepCopy() { 30 | QuestProgressMoneyRequirement qpmr = new QuestProgressMoneyRequirement(); 31 | qpmr.setMoney(getMoney()); 32 | qpmr.setOrder(getOrder()); 33 | return qpmr; 34 | } 35 | 36 | public int getMoney() { 37 | return money; 38 | } 39 | 40 | public void setMoney(int money) { 41 | this.money = money; 42 | } 43 | 44 | 45 | public void addMoney(int money) { 46 | setMoney(getMoney() + money); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/progress/QuestProgressRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.progress; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import javax.persistence.Column; 8 | import javax.persistence.DiscriminatorColumn; 9 | import javax.persistence.Entity; 10 | import javax.persistence.GeneratedValue; 11 | import javax.persistence.GenerationType; 12 | import javax.persistence.Id; 13 | import javax.persistence.Inheritance; 14 | import javax.persistence.InheritanceType; 15 | import javax.persistence.Table; 16 | 17 | /** 18 | * @author fair 19 | * @version V1.0 20 | * @Package im.cave.ms.client.quest 21 | * @date 11/27 20:47 22 | */ 23 | @Entity 24 | @Getter 25 | @Setter 26 | @Inheritance(strategy = InheritanceType.SINGLE_TABLE) 27 | @Table(name = "quest_progressrequirement") 28 | @DiscriminatorColumn(name = "progressType") 29 | public abstract class QuestProgressRequirement { 30 | @Id 31 | @GeneratedValue(strategy = GenerationType.IDENTITY) 32 | private int id; 33 | @Column(name = "orderNum") 34 | private int order = 999; 35 | 36 | public abstract boolean isComplete(MapleCharacter chr); 37 | 38 | public abstract QuestProgressRequirement deepCopy(); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/progress/QuestProgressRequirementType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.progress; 2 | 3 | import java.util.Arrays; 4 | 5 | public enum QuestProgressRequirementType { 6 | ITEM(0), 7 | LEVEL(1), 8 | MOB(2), 9 | MONEY(3); 10 | 11 | private final byte val; 12 | 13 | QuestProgressRequirementType(int val) { 14 | this.val = (byte) val; 15 | } 16 | 17 | public byte getVal() { 18 | return val; 19 | } 20 | 21 | public static QuestProgressRequirementType getQPRTByObj(Object o) { 22 | return o instanceof QuestProgressItemRequirement ? ITEM : 23 | o instanceof QuestProgressLevelRequirement ? LEVEL : 24 | o instanceof QuestProgressMobRequirement ? MOB : 25 | o instanceof QuestProgressMoneyRequirement ? MONEY : null; 26 | } 27 | 28 | public static QuestProgressRequirementType getQPRTByVal(byte val) { 29 | return Arrays.stream(QuestProgressRequirementType.values()) 30 | .filter(qprt -> qprt.getVal() == val).findFirst().orElse(null); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartCompletionRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | 6 | public class QuestStartCompletionRequirement implements QuestStartRequirement { 7 | private int questID; 8 | private byte questStatus; 9 | 10 | public QuestStartCompletionRequirement() { 11 | } 12 | 13 | public QuestStartCompletionRequirement(int questID, byte questStatus) { 14 | this.questID = questID; 15 | this.questStatus = questStatus; 16 | } 17 | 18 | public int getQuestID() { 19 | return questID; 20 | } 21 | 22 | public byte getQuestStatus() { 23 | return questStatus; 24 | } 25 | 26 | public void setQuestID(int questID) { 27 | this.questID = questID; 28 | } 29 | 30 | public void setQuestStatus(byte questStatus) { 31 | this.questStatus = questStatus; 32 | } 33 | 34 | @Override 35 | public boolean hasRequirements(MapleCharacter chr) { 36 | // QuestManager qm = chr.getQuestManager(); 37 | // switch (getQuestStatus()) { 38 | //// case 0: // Not started 39 | //// return !qm.hasQuestInProgress(getQuestID()) && !qm.hasQuestCompleted(getQuestID()); 40 | //// case 1: // In progress 41 | //// return qm.hasQuestInProgress(getQuestID()); 42 | // case 0: // Completed 43 | // return qm.hasQuestCompleted(getQuestID()); 44 | // default: 45 | // log.error(String.format("Unknown status %d.", getQuestStatus())); 46 | // return true; 47 | // } 48 | return true; 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartItemRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | 6 | public class QuestStartItemRequirement implements QuestStartRequirement { 7 | private int id; 8 | private int quantity; 9 | 10 | public int getId() { 11 | return id; 12 | } 13 | 14 | public void setId(int id) { 15 | this.id = id; 16 | } 17 | 18 | public int getQuantity() { 19 | return quantity; 20 | } 21 | 22 | public void setQuantity(int quantity) { 23 | this.quantity = quantity; 24 | } 25 | 26 | public void addReqItem(int reqItem, int count) { 27 | setId(reqItem); 28 | setQuantity(count); 29 | } 30 | 31 | @Override 32 | public boolean hasRequirements(MapleCharacter chr) { 33 | return chr.hasItemCount(getId(), getQuantity()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartJobRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | 9 | public class QuestStartJobRequirement implements QuestStartRequirement { 10 | private final Set jobReq; 11 | 12 | public QuestStartJobRequirement() { 13 | this.jobReq = new HashSet<>(); 14 | } 15 | 16 | public Set getJobReq() { 17 | return jobReq; 18 | } 19 | 20 | public void addJobReq(short job) { 21 | getJobReq().add(job); 22 | } 23 | 24 | @Override 25 | public boolean hasRequirements(MapleCharacter chr) { 26 | return getJobReq().contains(chr.getJob()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartMarriageRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | 6 | public class QuestStartMarriageRequirement implements QuestStartRequirement { 7 | @Override 8 | public boolean hasRequirements(MapleCharacter chr) { 9 | return chr.isMarried(); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartMaxLevelRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | 6 | public class QuestStartMaxLevelRequirement implements QuestStartRequirement { 7 | 8 | private short level; 9 | 10 | public QuestStartMaxLevelRequirement(short level) { 11 | this.level = level; 12 | } 13 | 14 | public QuestStartMaxLevelRequirement() { 15 | 16 | } 17 | 18 | private short getLevel() { 19 | return level; 20 | } 21 | 22 | @Override 23 | public boolean hasRequirements(MapleCharacter chr) { 24 | return chr.getLevel() <= getLevel(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartMinStatRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.character.Stat; 5 | 6 | 7 | public class QuestStartMinStatRequirement implements QuestStartRequirement { 8 | 9 | private Stat stat; 10 | private short reqAmount; 11 | 12 | public QuestStartMinStatRequirement(Stat stat, short reqAmount) { 13 | this.reqAmount = reqAmount; 14 | this.stat = stat; 15 | } 16 | 17 | public QuestStartMinStatRequirement() { 18 | 19 | } 20 | 21 | private void setReqAmount(short reqAmount) { 22 | this.reqAmount = reqAmount; 23 | } 24 | 25 | private short getReqAmount() { 26 | return reqAmount; 27 | } 28 | 29 | private Stat getStat() { 30 | return stat; 31 | } 32 | 33 | @Override 34 | public boolean hasRequirements(MapleCharacter chr) { 35 | return chr.getStat(getStat()) >= getReqAmount(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartRequirement.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | public interface QuestStartRequirement { 6 | 7 | boolean hasRequirements(MapleCharacter chr); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/requirement/QuestStartRequirementType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.requirement; 2 | 3 | import java.util.Arrays; 4 | 5 | public enum QuestStartRequirementType { 6 | 7 | QUEST(0), 8 | ITEM(1), 9 | JOB(2), 10 | MARRIAGE(3), 11 | MAX_LEVEL(4), 12 | MIN_STAT(5); 13 | 14 | private final byte val; 15 | 16 | QuestStartRequirementType(int val) { 17 | this.val = (byte) val; 18 | } 19 | 20 | public byte getVal() { 21 | return val; 22 | } 23 | 24 | public static QuestStartRequirementType getQPRTByObj(Object o) { 25 | return o instanceof QuestStartCompletionRequirement ? QUEST : 26 | o instanceof QuestStartItemRequirement ? ITEM : 27 | o instanceof QuestStartJobRequirement ? JOB : 28 | o instanceof QuestStartMarriageRequirement ? MARRIAGE : 29 | o instanceof QuestStartMaxLevelRequirement ? MAX_LEVEL : 30 | o instanceof QuestStartMinStatRequirement ? MIN_STAT 31 | : null; 32 | } 33 | 34 | public static QuestStartRequirementType getQPRTByVal(byte val) { 35 | return Arrays.stream(QuestStartRequirementType.values()) 36 | .filter(qprt -> qprt.getVal() == val).findFirst().orElse(null); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/reward/QuestBuffItemReward.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.reward; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.character.items.ItemBuffs; 5 | 6 | public class QuestBuffItemReward implements QuestReward { 7 | private int buffItemID; 8 | private int status; 9 | 10 | public QuestBuffItemReward(int buffItemID, int status) { 11 | this.buffItemID = buffItemID; 12 | this.status = status; 13 | } 14 | 15 | public QuestBuffItemReward() { 16 | } 17 | 18 | public int getBuffItemID() { 19 | return buffItemID; 20 | } 21 | 22 | public void setBuffItemID(int buffItemID) { 23 | this.buffItemID = buffItemID; 24 | } 25 | 26 | public void setStatus(int status) { 27 | this.status = status; 28 | } 29 | 30 | public int getStatus() { 31 | return status; 32 | } 33 | 34 | @Override 35 | public void giveReward(MapleCharacter chr) { 36 | ItemBuffs.giveItemBuffsFromItemID(chr, getBuffItemID()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/reward/QuestExpReward.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.reward; 2 | 3 | import im.cave.ms.client.character.ExpIncreaseInfo; 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.tools.Util; 6 | 7 | 8 | public class QuestExpReward implements QuestReward { 9 | 10 | private long exp; 11 | 12 | public QuestExpReward(long exp) { 13 | this.exp = exp; 14 | } 15 | 16 | public QuestExpReward() { 17 | 18 | } 19 | 20 | public void setExp(long exp) { 21 | this.exp = exp; 22 | } 23 | 24 | public long getExp() { 25 | return exp; 26 | } 27 | 28 | @Override 29 | public void giveReward(MapleCharacter chr) { 30 | ExpIncreaseInfo eii = new ExpIncreaseInfo(); 31 | eii.setLastHit(true); 32 | eii.setIncEXP(Util.maxInt(getExp())); 33 | eii.setOnQuest(true); 34 | chr.addExp(getExp(), eii); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/reward/QuestMoneyReward.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.reward; 2 | 3 | 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.connection.packet.UserPacket; 6 | 7 | 8 | public class QuestMoneyReward implements QuestReward { 9 | private long money; 10 | 11 | public QuestMoneyReward(long money) { 12 | this.money = money; 13 | } 14 | 15 | public QuestMoneyReward() { 16 | 17 | } 18 | 19 | public long getMoney() { 20 | return money; 21 | } 22 | 23 | public void setMoney(long money) { 24 | this.money = money; 25 | } 26 | 27 | 28 | @Override 29 | public void giveReward(MapleCharacter chr) { 30 | chr.addMeso(money); 31 | chr.announce(UserPacket.incMoneyMessage((int) money)); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/reward/QuestPopReward.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.reward; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.character.Stat; 5 | import im.cave.ms.connection.packet.UserPacket; 6 | import im.cave.ms.enums.MessageType; 7 | 8 | 9 | public class QuestPopReward implements QuestReward { 10 | 11 | private int pop; 12 | 13 | public QuestPopReward(int pop) { 14 | this.pop = pop; 15 | } 16 | 17 | public QuestPopReward() { 18 | 19 | } 20 | 21 | public int getPop() { 22 | return pop; 23 | } 24 | 25 | public void setPop(int pop) { 26 | this.pop = pop; 27 | } 28 | 29 | @Override 30 | public void giveReward(MapleCharacter chr) { 31 | chr.addStat(Stat.FAME, getPop()); 32 | chr.announce(UserPacket.message(MessageType.INC_POP_MESSAGE, getPop(), null, (byte) 0)); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/reward/QuestReward.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.reward; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | 5 | 6 | public interface QuestReward { 7 | 8 | void giveReward(MapleCharacter chr); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/quest/reward/QuestRewardType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.quest.reward; 2 | 3 | import java.util.Arrays; 4 | 5 | 6 | public enum QuestRewardType { 7 | EXP(0), 8 | ITEM(1), 9 | MONEY(2), 10 | POP(3), 11 | BUFF_ITEM(4); 12 | 13 | private final byte val; 14 | 15 | QuestRewardType(int val) { 16 | this.val = (byte) val; 17 | } 18 | 19 | public byte getVal() { 20 | return val; 21 | } 22 | 23 | public static QuestRewardType getQuestRewardType(Object o) { 24 | return o instanceof QuestExpReward ? EXP : 25 | o instanceof QuestItemReward ? ITEM : 26 | o instanceof QuestMoneyReward ? MONEY : 27 | o instanceof QuestPopReward ? POP : 28 | o instanceof QuestBuffItemReward ? BUFF_ITEM : null; 29 | } 30 | 31 | public static QuestRewardType getQuestRewardType(byte val) { 32 | return Arrays.stream(QuestRewardType.values()) 33 | .filter(qprt -> qprt.getVal() == val).findFirst().orElse(null); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/client/storage/Locker.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.client.storage; 2 | 3 | import im.cave.ms.client.character.items.Item; 4 | import im.cave.ms.connection.db.DataBaseManager; 5 | import im.cave.ms.constants.GameConstants; 6 | 7 | import javax.persistence.DiscriminatorValue; 8 | import javax.persistence.Entity; 9 | 10 | /** 11 | * @author fair 12 | * @version V1.0 13 | * @Package im.cave.ms.client.trunk 14 | * @date 1/6 23:59 15 | */ 16 | @Entity 17 | @DiscriminatorValue("Locker") 18 | public class Locker extends Storage { 19 | 20 | public Locker() { 21 | super(GameConstants.MAX_LOCKER_SIZE); 22 | } 23 | 24 | @Override 25 | public void putItem(Item item, int quantity) { 26 | getItems().add(item); 27 | if (item.getId() == 0) { 28 | DataBaseManager.saveToDB(this); 29 | } 30 | } 31 | 32 | @Override 33 | public void sort(boolean proactive) { 34 | //todo 35 | } 36 | 37 | public Item getItemBySerialNumber(long serialNumber) { 38 | return getItems().stream().filter(item -> item.getCashItemSerialNumber() == serialNumber).findAny().orElse(null); 39 | } 40 | 41 | public void removeItemBySerialNumber(long serialNumber) { 42 | getItems().removeIf(item -> item.getCashItemSerialNumber() == serialNumber); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/configs/Config.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.configs; 2 | 3 | import com.esotericsoftware.yamlbeans.YamlReader; 4 | 5 | import java.io.File; 6 | import java.io.FileNotFoundException; 7 | import java.io.FileReader; 8 | import java.io.IOException; 9 | 10 | /** 11 | * @author fair 12 | * @version V1.0 13 | * @Package im.cave.ms.provider 14 | * @date 12/28 16:01 15 | */ 16 | public class Config { 17 | public static ServerConfig serverConfig = (ServerConfig) loadConfig("server.yml", ServerConfig.class); 18 | public static WorldConfig worldConfig = (WorldConfig) loadConfig("world.yml", WorldConfig.class); 19 | 20 | public static Object loadConfig(String filename, Class clazz) { 21 | try { 22 | File file = new File("configs/" + filename); 23 | YamlReader reader = new YamlReader(new FileReader(file)); 24 | Object config = reader.read(clazz); 25 | reader.close(); 26 | return config; 27 | } catch (FileNotFoundException e) { 28 | String message = "Could not read config file " + filename + ": " + e.getMessage(); 29 | throw new RuntimeException(message); 30 | } catch (IOException e) { 31 | String message = "Could not successfully parse config file " + filename + ": " + e.getMessage(); 32 | throw new RuntimeException(message); 33 | } 34 | } 35 | 36 | public static void reload() { 37 | serverConfig = (ServerConfig) loadConfig("server-config.yml", ServerConfig.class); 38 | worldConfig = (WorldConfig) loadConfig("worldId-config.yml", WorldConfig.class); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/configs/ServerConfig.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.configs; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.config 9 | * @date 11/19 23:36 10 | */ 11 | public class ServerConfig { 12 | public boolean AUTOMATIC_REGISTER; 13 | public List CLOSED_JOBS; 14 | public boolean MIGRATE_IN_AFTER_CREATE_CHAR; 15 | public boolean SHOW_UNKNOWN_PACKET; 16 | public boolean DEBUG; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/configs/WorldConfig.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.configs; 2 | 3 | import im.cave.ms.client.MapleDailyGift; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author fair 9 | * @version V1.0 10 | * @Package im.cave.ms.config 11 | * @date 11/19 23:30 12 | */ 13 | public class WorldConfig { 14 | 15 | public List worlds; 16 | public List dailyGifts; 17 | 18 | public WorldInfo getWorldInfo(int worldId) { 19 | return worlds.stream().filter(world -> world.id == worldId).findAny().orElse(null); 20 | } 21 | 22 | public List getDailyGiftsRewards() { 23 | return dailyGifts; 24 | } 25 | 26 | public static class WorldInfo { 27 | public int id = 0; 28 | public int flag = 0; 29 | public String server_message = "Welcome!"; 30 | public String event_message = ""; 31 | public int channels = 1; 32 | public int exp_rate = 1; 33 | public int meso_rate = 1; 34 | public int drop_rate = 1; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/crypto/TripleDESCipher.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.crypto; 2 | 3 | import javax.crypto.Cipher; 4 | import javax.crypto.spec.SecretKeySpec; 5 | import java.security.Key; 6 | 7 | /** 8 | * @author fair 9 | * @version V1.0 10 | * @Package net.mina 11 | * @date 11/9 8:53 12 | */ 13 | public class TripleDESCipher { 14 | public byte[] aKey = new byte[24]; 15 | public Key pKey; 16 | 17 | public TripleDESCipher(byte[] aKey) { 18 | System.arraycopy(aKey, 0, this.aKey, 0, aKey.length); 19 | this.pKey = new SecretKeySpec(aKey, "DESede"); 20 | } 21 | 22 | public byte[] Encrypt(byte[] aData) throws Exception { 23 | Cipher pCipher = Cipher.getInstance("DESede"); 24 | pCipher.init(Cipher.ENCRYPT_MODE, this.pKey); 25 | return pCipher.doFinal(aData); 26 | } 27 | 28 | public byte[] Decrypt(byte[] aData) throws Exception { 29 | Cipher pCipher = Cipher.getInstance("DESede"); 30 | pCipher.init(Cipher.DECRYPT_MODE, this.pKey); 31 | return pCipher.doFinal(aData); 32 | } 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/db/InlinedIntArrayConverter.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.db; 2 | 3 | 4 | import javax.persistence.AttributeConverter; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | 9 | public class InlinedIntArrayConverter implements AttributeConverter, String> { 10 | @Override 11 | public String convertToDatabaseColumn(List integers) { 12 | StringBuilder sb = new StringBuilder(); 13 | if (integers == null) { 14 | return null; 15 | } 16 | for (int i : integers) { 17 | sb.append(i).append(","); 18 | } 19 | String res; 20 | if (integers.size() > 0) { 21 | res = sb.substring(0, sb.length() - 1); // removes last comma 22 | } else { 23 | res = ""; 24 | } 25 | return res; 26 | } 27 | 28 | @Override 29 | public List convertToEntityAttribute(String s) { 30 | if (s == null) { 31 | return null; 32 | } 33 | String[] split = s.split(","); 34 | List ints = new ArrayList<>(); 35 | if (split.length > 0 && split[0].length() > 0) { 36 | for (String str : split) { 37 | ints.add(Integer.valueOf(str)); 38 | } 39 | } 40 | return ints; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/netty/Packet.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.netty; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | public class Packet implements Cloneable { 6 | 7 | private byte[] data; 8 | 9 | public Packet(byte[] data) { 10 | this.data = new byte[data.length]; 11 | System.arraycopy(data, 0, this.data, 0, data.length); 12 | } 13 | 14 | public int getLength() { 15 | if (data != null) { 16 | return data.length; 17 | } 18 | return 0; 19 | } 20 | 21 | public int getHeader() { 22 | if (data.length < 2) { 23 | return 0xFFFF; 24 | } 25 | return (data[0] + (data[1] << 8)); 26 | } 27 | 28 | public void release() { 29 | this.data = null; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | if (data == null) return ""; 35 | return "[Packet] | " + Util.readableByteArray(data); 36 | } 37 | 38 | @Override 39 | public Packet clone() { 40 | return new Packet(data); 41 | } 42 | 43 | public byte[] getData() { 44 | return data; 45 | 46 | } 47 | 48 | public void setData(byte[] data) { 49 | this.data = data; 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/netty/ServerAcceptor.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.netty; 2 | 3 | import im.cave.ms.connection.server.AbstractServer; 4 | import io.netty.bootstrap.ServerBootstrap; 5 | import io.netty.channel.ChannelFuture; 6 | import io.netty.channel.ChannelOption; 7 | import io.netty.channel.EventLoopGroup; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.nio.NioServerSocketChannel; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | /** 14 | * @author fair 15 | * @version V1.0 16 | * @Package im.cave.ms.connection.netty 17 | * @date 11/19 17:00 18 | */ 19 | public class ServerAcceptor implements Runnable { 20 | public AbstractServer server; 21 | private static final Logger log = LoggerFactory.getLogger(ServerAcceptor.class); 22 | 23 | public ServerAcceptor(AbstractServer server) { 24 | this.server = server; 25 | } 26 | 27 | @Override 28 | public void run() { 29 | EventLoopGroup bossGroup = new NioEventLoopGroup(); 30 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 31 | try { 32 | ServerBootstrap sb = new ServerBootstrap(); 33 | sb.group(bossGroup, workerGroup); 34 | sb.channel(NioServerSocketChannel.class); 35 | sb.childHandler(new ServerInitializer(server)); 36 | sb.childOption(ChannelOption.TCP_NODELAY, true); 37 | sb.childOption(ChannelOption.SO_KEEPALIVE, true); 38 | ChannelFuture channelFuture = sb.bind(server.getPort()).sync(); 39 | channelFuture.channel().closeFuture().sync(); 40 | } catch (Exception e) { 41 | log.error("端口:{} 被占用", server.getPort()); 42 | } finally { 43 | workerGroup.shutdownGracefully(); 44 | bossGroup.shutdownGracefully(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/packet/AndroidPacket.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.packet; 2 | 3 | import im.cave.ms.client.field.movement.MovementInfo; 4 | import im.cave.ms.client.field.obj.Android; 5 | import im.cave.ms.connection.netty.OutPacket; 6 | import im.cave.ms.connection.packet.opcode.SendOpcode; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.network.packet 12 | * @date 1/1 16:54 13 | */ 14 | public class AndroidPacket { 15 | 16 | public static OutPacket created(Android android) { 17 | OutPacket out = new OutPacket(); 18 | out.writeShort(SendOpcode.ANDROID_CREATED.getValue()); 19 | out.writeInt(android.getOwner().getId()); 20 | android.encode(out); 21 | return out; 22 | } 23 | 24 | public static OutPacket remove(int charId) { 25 | OutPacket out = new OutPacket(); 26 | out.writeShort(SendOpcode.ANDROID_REMOVED.getValue()); 27 | out.writeInt(charId); 28 | return out; 29 | } 30 | 31 | public static OutPacket actionSet(Android android, int action, int emotion) { 32 | OutPacket out = new OutPacket(SendOpcode.ANDROID_ACTION_SET); 33 | 34 | out.writeInt(android.getOwner().getId()); 35 | out.write(action); 36 | out.write(emotion); 37 | 38 | return out; 39 | } 40 | 41 | public static OutPacket modified(Android android) { 42 | OutPacket out = new OutPacket(); 43 | out.writeShort(SendOpcode.ANDROID_MODIFIED.getValue()); 44 | out.writeInt(android.getOwner().getId()); 45 | 46 | return out; 47 | 48 | } 49 | 50 | public static OutPacket move(Android android, MovementInfo mi) { 51 | OutPacket out = new OutPacket(); 52 | out.writeShort(SendOpcode.ANDROID_MOVE.getValue()); 53 | out.writeInt(android.getOwner().getId()); 54 | mi.encode(out); 55 | return out; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/packet/AuctionPacket.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.packet; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.character.items.AuctionRecord; 5 | import im.cave.ms.connection.netty.OutPacket; 6 | import im.cave.ms.connection.packet.opcode.SendOpcode; 7 | import im.cave.ms.enums.AuctionAction; 8 | 9 | import java.util.List; 10 | 11 | import static im.cave.ms.constants.ServerConstants.ZERO_TIME; 12 | 13 | /** 14 | * @author fair 15 | * @version V1.0 16 | * @Package im.cave.ms.connection.packet 17 | * @date 2/5 10:28 18 | */ 19 | public class AuctionPacket { 20 | 21 | public static OutPacket getWrapToAuction(MapleCharacter player) { 22 | OutPacket out = new OutPacket(SendOpcode.SET_AUCTION); 23 | PacketHelper.addCharInfo(out, player); 24 | return out; 25 | } 26 | 27 | public static OutPacket quotation(List records) { 28 | OutPacket out = new OutPacket(SendOpcode.AUCTION); 29 | 30 | out.writeInt(AuctionAction.QuickSearch.getVal()); 31 | out.writeLong(1000); //mask 32 | out.write(1); //金币 33 | out.write(0); //抵用券 34 | out.writeInt(records.size()); 35 | for (AuctionRecord record : records) { 36 | record.encode(out); 37 | } 38 | 39 | return out; 40 | } 41 | 42 | 43 | public static OutPacket pullOnSellDone(AuctionRecord record) { 44 | OutPacket out = new OutPacket(SendOpcode.AUCTION); 45 | 46 | out.writeInt(AuctionAction.Put_On_Sell.getVal()); 47 | out.writeInt(0); 48 | out.writeInt(record.getId()); 49 | out.write(1); 50 | record.encode(out); 51 | 52 | return out; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/packet/FieldAttackObjPacket.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.packet; 2 | 3 | import im.cave.ms.client.field.FieldAttackObj; 4 | import im.cave.ms.connection.netty.OutPacket; 5 | import im.cave.ms.connection.packet.opcode.SendOpcode; 6 | 7 | /** 8 | * @author fair 9 | * @version V1.0 10 | * @Package im.cave.ms.connection.packet 11 | * @date 4/2 10:42 12 | */ 13 | public class FieldAttackObjPacket { 14 | public static OutPacket objCreate(FieldAttackObj fao) { 15 | OutPacket out = new OutPacket(SendOpcode.FIELD_ATTACK_CREATE); 16 | 17 | fao.encode(out); 18 | 19 | return out; 20 | } 21 | 22 | public static OutPacket setAttack(int objectId, int attackIdx) { 23 | OutPacket out = new OutPacket(SendOpcode.FIELD_ATTACK_SET_ATTACK); 24 | 25 | out.writeInt(objectId); 26 | out.writeInt(attackIdx); 27 | 28 | return out; 29 | } 30 | 31 | public static OutPacket objRemoveByKey(int objectID) { 32 | OutPacket out = new OutPacket(SendOpcode.FIELD_ATTACK_REMOVE_BY_KEY); 33 | 34 | out.writeInt(objectID); 35 | 36 | return out; 37 | } 38 | 39 | public static OutPacket objRemoveList(int templateId, int objId) { 40 | OutPacket out = new OutPacket(SendOpcode.FIELD_ATTACK_REMOVE_LIST); 41 | 42 | out.writeInt(templateId); 43 | out.writeInt(objId); 44 | 45 | return out; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/packet/ReactorPacket.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.packet; 2 | 3 | import im.cave.ms.client.field.obj.Reactor; 4 | import im.cave.ms.connection.netty.OutPacket; 5 | import im.cave.ms.connection.packet.opcode.SendOpcode; 6 | 7 | /** 8 | * @author fair 9 | * @version V1.0 10 | * @Package im.cave.ms.connection.packet 11 | * @date 2/7 11:58 12 | */ 13 | public class ReactorPacket { 14 | public static OutPacket reactorEnterField(Reactor reactor) { 15 | OutPacket out = new OutPacket(SendOpcode.REACTOR_ENTER_FIELD); 16 | 17 | out.writeInt(reactor.getObjectId()); 18 | out.writeInt(reactor.getTemplateId()); 19 | out.write(reactor.getState()); 20 | out.writePosition(reactor.getPosition()); 21 | out.writeBool(reactor.isFlip()); 22 | out.writeMapleAsciiString(reactor.getName()); 23 | 24 | return out; 25 | } 26 | 27 | 28 | public static OutPacket reactorChangeState(Reactor reactor, short delay, byte stateLength) { 29 | OutPacket out = new OutPacket(SendOpcode.REACTOR_CHANGE_STATE); 30 | 31 | out.writeInt(reactor.getObjectId()); 32 | out.write(reactor.getState()); 33 | out.writePosition(reactor.getPosition()); 34 | out.writeShort(delay); 35 | out.write(reactor.getProperEventIdx()); 36 | out.writeInt(stateLength); 37 | out.writeInt(reactor.getOwnerId()); 38 | 39 | return out; 40 | } 41 | 42 | public static OutPacket remove(Reactor reactor) { 43 | OutPacket out = new OutPacket(SendOpcode.REACTOR_REMOVE); 44 | 45 | out.writeInt(reactor.getObjectId()); 46 | 47 | return out; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/packet/result/FameResult.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.packet.result; 2 | 3 | import im.cave.ms.connection.netty.OutPacket; 4 | import im.cave.ms.enums.FameAction; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.connection.packet.result 12 | * @date 3/25 8:57 13 | */ 14 | @Getter 15 | @Setter 16 | public class FameResult { 17 | private FameAction action; 18 | private String str; 19 | private int arg1; 20 | private int arg2; 21 | private int arg3; 22 | 23 | public static FameResult alreadyAddInThisMonth() { 24 | FameResult fameResult = new FameResult(); 25 | fameResult.action = FameAction.AlreadyAddInThisMonth; 26 | return fameResult; 27 | } 28 | 29 | public static FameResult receiveFame(String from, int mode) { 30 | FameResult fameResult = new FameResult(); 31 | fameResult.action = FameAction.Receive; 32 | fameResult.str = from; 33 | fameResult.arg1 = mode; 34 | return fameResult; 35 | } 36 | 37 | public static FameResult addFame(String to, int mode, int newFame) { 38 | FameResult fameResult = new FameResult(); 39 | fameResult.action = FameAction.Receive; 40 | fameResult.str = to; 41 | fameResult.arg1 = mode; 42 | fameResult.arg2 = newFame; 43 | return fameResult; 44 | } 45 | 46 | 47 | public static void encode(OutPacket out) { 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/packet/result/HotTimeRewardResult.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.packet.result; 2 | 3 | import im.cave.ms.client.HotTimeReward; 4 | import im.cave.ms.client.character.MapleCharacter; 5 | import im.cave.ms.enums.HotTimeRewardResultType; 6 | import lombok.Data; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author fair 12 | * @version V1.0 13 | * @Package im.cave.ms.connection.packet.result 14 | * @date 1/20 11:04 15 | */ 16 | @Data 17 | public class HotTimeRewardResult { 18 | private HotTimeRewardResultType type; 19 | private List rewards; 20 | private HotTimeReward reward; 21 | 22 | public static HotTimeRewardResult hotTimeRewardsList(MapleCharacter chr) { 23 | HotTimeRewardResult rewardResult = new HotTimeRewardResult(); 24 | rewardResult.setType(HotTimeRewardResultType.LIST); 25 | rewardResult.setRewards(chr.getHotTimeRewards()); 26 | return rewardResult; 27 | } 28 | 29 | public static HotTimeRewardResult getItem(HotTimeReward reward) { 30 | HotTimeRewardResult rewardResult = new HotTimeRewardResult(); 31 | rewardResult.setType(HotTimeRewardResultType.GET_ITEM); 32 | rewardResult.setReward(reward); 33 | return rewardResult; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/packet/result/MapleNotesResult.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.packet.result; 2 | 3 | import im.cave.ms.client.multiplayer.MapleNotes; 4 | import lombok.Data; 5 | import lombok.Getter; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author fair 11 | * @version V1.0 12 | * @Package im.cave.ms.connection.packet.result 13 | * @date 1/20 22:39 14 | */ 15 | @Data 16 | public class MapleNotesResult { 17 | private int arg1; 18 | private List notes; 19 | private MapleNotes note; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/AbstractServer.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server; 2 | 3 | import im.cave.ms.connection.netty.ServerAcceptor; 4 | import im.cave.ms.enums.ServerType; 5 | 6 | /** 7 | * @author fair 8 | * @version V1.0 9 | * @Package im.cave.ms.abstractServer 10 | * @date 11/19 16:23 11 | */ 12 | public abstract class AbstractServer { 13 | protected ServerType type; 14 | protected int port; 15 | protected int worldId; 16 | protected int channelId; 17 | protected ServerAcceptor acceptor; 18 | 19 | public AbstractServer(int worldId, int channelId) { 20 | this.worldId = worldId; 21 | this.channelId = channelId; 22 | } 23 | 24 | 25 | public int getChannelId() { 26 | return channelId; 27 | } 28 | 29 | public void setChannelId(int channelId) { 30 | this.channelId = channelId; 31 | } 32 | 33 | 34 | public int getWorldId() { 35 | return worldId; 36 | } 37 | 38 | public void setWorldId(int worldId) { 39 | this.worldId = worldId; 40 | } 41 | 42 | 43 | public int getPort() { 44 | return port; 45 | } 46 | 47 | public void setPort(int port) { 48 | this.port = port; 49 | } 50 | 51 | public ServerType getType() { 52 | return type; 53 | } 54 | 55 | public void setType(ServerType type) { 56 | this.type = type; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/ErrorPacketHandler.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server; 2 | 3 | 4 | import im.cave.ms.connection.netty.InPacket; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.connection.handler 12 | * @date 11/20 21:42 13 | */ 14 | public class ErrorPacketHandler { 15 | private static final Logger log = LoggerFactory.getLogger(ErrorPacketHandler.class); 16 | 17 | public static void handlePacket(InPacket in) { 18 | in.skip(6); 19 | short packetLength = in.readShort(); 20 | in.skip(4); 21 | int op = in.readShort(); 22 | byte[] packet = in.read(packetLength - 6); 23 | log.error("Send error opcode {} packet {} ", Integer.toHexString(op), packet); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/auction/Auction.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server.auction; 2 | 3 | import im.cave.ms.connection.netty.ServerAcceptor; 4 | import im.cave.ms.connection.server.AbstractServer; 5 | import im.cave.ms.constants.ServerConstants; 6 | import im.cave.ms.enums.ServerType; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.abstractServer.auction 12 | * @date 11/19 16:23 13 | */ 14 | public class Auction extends AbstractServer { 15 | 16 | 17 | public Auction(int worldId) { 18 | super(worldId, 21); 19 | type = ServerType.AUCTION; 20 | port = ServerConstants.AUCTION_PORT; 21 | acceptor = new ServerAcceptor(this); 22 | acceptor.server = this; 23 | new Thread(acceptor).start(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/auction/AuctionHandler.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server.auction; 2 | 3 | import im.cave.ms.connection.netty.InPacket; 4 | import im.cave.ms.connection.server.AbstractServerHandler; 5 | import im.cave.ms.enums.ServerType; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | /** 11 | * @author fair 12 | * @version V1.0 13 | * @Package im.cave.ms.connection.server.auction 14 | * @date 2/5 10:53 15 | */ 16 | public class AuctionHandler extends AbstractServerHandler { 17 | private static final Logger log = LoggerFactory.getLogger("Auction"); 18 | 19 | private final int world; 20 | 21 | public AuctionHandler(int world) { 22 | this.world = world; 23 | } 24 | 25 | @Override 26 | protected void channelRead0(ChannelHandlerContext channelHandlerContext, InPacket inPacket) throws Exception { 27 | 28 | } 29 | 30 | 31 | @Override 32 | public void channelActive(ChannelHandlerContext ctx) { 33 | log.info(" Join in World-{} Auction", world); 34 | connected(ctx, ServerType.AUCTION); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/login/LoginServer.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server.login; 2 | 3 | import im.cave.ms.connection.netty.ServerAcceptor; 4 | import im.cave.ms.connection.server.AbstractServer; 5 | import im.cave.ms.enums.ServerType; 6 | import im.cave.ms.tools.Pair; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.HashMap; 11 | import java.util.List; 12 | 13 | /** 14 | * @author fair 15 | * @version V1.0 16 | * @Package im.cave.ms.abstractServer.login 17 | * @date 11/19 16:22 18 | */ 19 | public class LoginServer extends AbstractServer { 20 | private static final Logger log = LoggerFactory.getLogger(LoginServer.class); 21 | private List accounts; 22 | private static LoginServer instance; 23 | private HashMap> loginAuthKey = new HashMap<>(); 24 | 25 | private LoginServer() { 26 | super(-1, -1); 27 | type = ServerType.LOGIN; 28 | port = 8484; 29 | acceptor = new ServerAcceptor(this); 30 | new Thread(acceptor).start(); 31 | log.info("登陆服务器启动成功 监听端口: {}", port); 32 | } 33 | 34 | public static LoginServer getInstance() { 35 | if (instance == null) { 36 | instance = new LoginServer(); 37 | } 38 | return instance; 39 | } 40 | 41 | public HashMap> getLoginAuthKey() { 42 | return loginAuthKey; 43 | } 44 | 45 | 46 | public void setLoginAuthKey(HashMap> loginAuthKey) { 47 | this.loginAuthKey = loginAuthKey; 48 | } 49 | 50 | public void putLoginAuthKey(String key, String account, int channel) { 51 | loginAuthKey.put(key, new Pair<>(account, channel)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/login/handler/ServerListHandler.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server.login.handler; 2 | 3 | import im.cave.ms.client.MapleClient; 4 | import im.cave.ms.connection.netty.InPacket; 5 | import im.cave.ms.connection.netty.OutPacket; 6 | import im.cave.ms.connection.packet.LoginPacket; 7 | 8 | import static im.cave.ms.enums.LoginStatus.LOGGEDIN; 9 | 10 | /** 11 | * @author fair 12 | * @version V1.0 13 | * @Package im.cave.ms.connection.handler.login 14 | * @date 11/20 21:50 15 | */ 16 | public class ServerListHandler { 17 | 18 | public static void serverStatus(InPacket in, MapleClient c) { 19 | validate(c); 20 | in.skip(1); 21 | int worldId = in.readInt(); 22 | c.announce(LoginPacket.sendSelectWorld(worldId)); 23 | } 24 | 25 | public static void serverList(MapleClient c) { 26 | for (OutPacket server : LoginPacket.worldInformation()) { 27 | c.announce(server); 28 | } 29 | c.announce(LoginPacket.worldInformationEnd()); 30 | } 31 | 32 | private static void validate(MapleClient c) { 33 | if (c.getLoginStatus() == LOGGEDIN) { 34 | return; 35 | } 36 | c.close(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/service/task/ExpiredItemRecycle.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server.service.task; 2 | 3 | import im.cave.ms.client.character.MapleCharacter; 4 | import im.cave.ms.client.character.items.Inventory; 5 | import im.cave.ms.connection.server.service.EventManager; 6 | import im.cave.ms.enums.InventoryType; 7 | import im.cave.ms.tools.DateUtil; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | import java.util.concurrent.ScheduledFuture; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * 对在线角色的过期道具进行回收 16 | * 为在线角色的过期道具将于角色登录后进行回收 17 | * 18 | * @author fair 19 | * @version V1.0 20 | * @Package im.cave.ms.connection.server.service 21 | * @date 2/18 15:54 22 | */ 23 | public class ExpiredItemRecycle { 24 | private static final Map> tasks = new HashMap<>(); 25 | 26 | public static void remove(MapleCharacter chr) { 27 | if (tasks.containsKey(chr)) { 28 | tasks.get(chr).cancel(true); 29 | tasks.remove(chr); 30 | } 31 | } 32 | 33 | public static void add(MapleCharacter chr) { 34 | ScheduledFuture scheduledFuture = EventManager.addFixedRateEvent(() -> run(chr), 0, 5, TimeUnit.MINUTES); 35 | tasks.put(chr, scheduledFuture); 36 | } 37 | 38 | public static void run(MapleCharacter chr) { 39 | long currentFileTime = DateUtil.getFileTime(System.currentTimeMillis()); 40 | for (InventoryType value : InventoryType.values()) { 41 | Inventory inventory = chr.getInventory(value); 42 | if (inventory == null) { 43 | continue; 44 | } 45 | inventory.getItems().removeIf(item -> item.getExpireTime() < currentFileTime); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/connection/server/service/task/RecordClear.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.connection.server.service.task; 2 | 3 | /** 4 | * 清除日常记录 5 | * 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.connection.server.service.task 9 | * @date 2/18 16:27 10 | */ 11 | public class RecordClear { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/constants/MatrixConstants.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.constants; 2 | 3 | 4 | import im.cave.ms.provider.data.VCoreData; 5 | 6 | public class MatrixConstants { 7 | // Etc.wz/VMatrixOption.img 8 | public static final int SLOT_MAX = 500; 9 | public static final int EQUIP_SLOT_MIN = 4; 10 | public static final int EQUIP_SLOT_MAX = 15; 11 | public static final int SPECIAL_SLOT_MAX = 1; 12 | public static final int EXTEND_LEVEL = 5; 13 | public static final int EXTEND_AF = 0; 14 | public static final int GRADE_MAX = 25; 15 | public static final int TOTAL_GRADE_MAX = 50; 16 | public static final int CRAFT_SKILL_CORE_COST = 140; 17 | public static final int CRAFT_ENCHANT_CORE_COST = 70; 18 | public static final int CRAFT_SPECIAL_CORE_COST = 250; 19 | public static final int CRAFT_GEMSTONE_COST = 35; 20 | public static final int MATRIX_POINT_RESET_MESO = 1000000; 21 | public static final int EQUIP_SLOT_ENHANCE_MAX = 5; 22 | // slotExpansionMeso can be helpful 23 | 24 | public static int getIncShard(int coreID, int skillLevel) { 25 | int shard = 0; 26 | if (VCoreData.isSkillNode(coreID)) { 27 | shard = VCoreData.getEnforceOption(VCoreData.SKILL).get(skillLevel).getExtract(); 28 | } else if (VCoreData.isBoostNode(coreID)) { 29 | shard = VCoreData.getEnforceOption(VCoreData.BOOST).get(skillLevel).getExtract(); 30 | } else if (VCoreData.isSpecialNode(coreID)) { 31 | shard = VCoreData.getEnforceOption(VCoreData.SPECIAL).get(skillLevel).getExtract(); 32 | } else if (VCoreData.isExpNode(coreID)) { 33 | shard = VCoreData.getEnforceOption(VCoreData.EXP).get(skillLevel).getExtract(); 34 | } 35 | return shard; 36 | } 37 | 38 | public static int getSlotsByLevel(int level) { 39 | int slotByLevel = level / 5 - 40; 40 | return Math.min(slotByLevel, EQUIP_SLOT_MAX); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/constants/ServerConstants.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.constants; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.constant 7 | * @date 11/19 21:48 8 | */ 9 | public class ServerConstants { 10 | 11 | public static final long MAX_TIME = 150842304000000000L; 12 | public static final long ZERO_TIME = 94354848000000000L; 13 | public static final long ONE_DAY_TIMES = 60 * 60 * 24 * 1000L; 14 | public static final short VERSION = 179; 15 | public static final String PATH = "1"; 16 | public static final int LOGIN_PORT = 8484; 17 | public static final int CASH_SHOP_PORT = 8600; 18 | public static final int AUCTION_PORT = 8900; 19 | public static final int BCRYPT_ITERATIONS = 10; 20 | public static final String DIR = System.getProperty("user.dir"); 21 | public static final String WZ_DIR = DIR + "/wz"; 22 | public static final String SCRIPT_DIR = DIR + "/scripts/"; 23 | public static final byte[] NEXON_IP = new byte[]{(byte) 0xDD, (byte) 0xE7, (byte) 0x82, (byte) 0x46}; 24 | public final static byte[] DES_KEY = new byte[]{0x61, 0x56, 0x62, 0x54, 0x70, 0x4A, 0x35, 0x3D, 0x5A, 0x6A, 0x47, 0x26, 0x44, 0x62, 0x33, 0x24, 0x61, 0x56, 0x62, 0x54, 0x70, 0x4A, 0x35, 0x3D}; 25 | //aVbTpJ5=ZjG&Db3$ 178 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ArcEnchantType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | public enum ArcEnchantType { 6 | Absorbing_Single(0), 7 | Upgrade(1), 8 | Absorbing_Multi(2), 9 | ; 10 | private final int val; 11 | 12 | 13 | public static ArcEnchantType getEnchantTypeByVal(int val) { 14 | return Util.findWithPred(values(), auctionAction -> auctionAction.getVal() == val); 15 | } 16 | 17 | ArcEnchantType(int val) { 18 | this.val = val; 19 | } 20 | 21 | public int getVal() { 22 | return val; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/AssistType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum AssistType { //Summon Assist Type 5 | None(0), 6 | Attack(1), 7 | Heal(2), 8 | AttackEx(3), 9 | AttackEx2(4), 10 | Summon(5), 11 | AttackManual(6), 12 | AttackCounter(7), 13 | CreateArea(8), 14 | Bodyguard(9), 15 | Jaguar(10), 16 | ; 17 | private final byte val; 18 | 19 | AssistType(int val) { 20 | this.val = (byte) val; 21 | } 22 | 23 | public byte getVal() { 24 | return val; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/AuctionAction.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 2/5 10:31 10 | */ 11 | public enum AuctionAction { 12 | Put_On_Sell(10), 13 | Pull_Off_Shelves(12), 14 | Search(40), 15 | QuickSearch(41), 16 | Sell_List(70); 17 | 18 | 19 | private final int val; 20 | 21 | 22 | AuctionAction(int val) { 23 | this.val = val; 24 | } 25 | 26 | public static AuctionAction getActionByVal(int val) { 27 | return Util.findWithPred(values(), auctionAction -> auctionAction.getVal() == val); 28 | } 29 | 30 | public int getVal() { 31 | return val; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/BroadcastMsgType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * Created by Asura on 16-6-2018. 5 | */ 6 | public enum BroadcastMsgType { 7 | // Types 8 | TYPE_ALL(0), 9 | TYPE_CLONE(1), 10 | TYPE_MAP(2), 11 | // Messages 12 | NOTICE(0), 13 | ALERT(1), 14 | SPEAKER_CHANNEL(2), 15 | SPEAKER_WORLD(3), 16 | SLIDE(4), 17 | EVENT(5), 18 | NOTICE_WITH_OUT_PREFIX(6), //38 19 | UTIL_DLG_EX(7), 20 | ITEM_SPEAKER(8), // Holds item info 21 | SPEAKER_BRIDGE(9), 22 | ART_SPEAKER_WORLD(10), 23 | GACHAPON_MSG(11), // item shown when clicked, does hold Item info 24 | BLOW_WEATHER(12), // TODO Contains PackedCharLook 25 | ANNOUNCED_QUEST_OPEN(13), // tries to auto start quests with the announcement (?) - probably the "A quest has arrived! Please clock on the icon at the botfom of your screen." 26 | ANNOUNCED_QUEST_CLOSED(14), // tries to auto start quests (?) 27 | MIRACLE_TIME(15), // Repeats the string 3x on the same line 28 | EVENT_MSG_WITH_CHANNEL(16), // May be for /find ? 29 | LOTTERY_ITEM_SPEAKER(17), // Holds item info 30 | LOTTERY_ITEM_SPEAKER_WORLD(18), 31 | MONSTER_LIFE_WORLD_MSG(19), 32 | NOTICE_WINDOW(20), 33 | PICKUP_ITEM_WORLD(22), 34 | SPEAKER_WORLD_GUILD_SKILL(23), 35 | WEATHER_MSG(24), // TODO Contains PackedCharLook 36 | UNK25(25), 37 | UNK26(26), 38 | UNK27(27), 39 | UNK28(28), 40 | UNK29(29), 41 | UNK30(30), 42 | UNK31(31), 43 | UNK32(32), 44 | UNK33(33), 45 | WITH_ITEM(34), 46 | UNK35(35), 47 | UNK36(36), 48 | PINK(40), 49 | YELLOW_BLACK(50), 50 | LOVE(51), 51 | ; 52 | private final byte val; 53 | 54 | BroadcastMsgType(int val) { 55 | this.val = (byte) val; 56 | } 57 | 58 | public byte getVal() { 59 | return val; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/CashShopCurrencyType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 1/6 22:37 10 | */ 11 | public enum CashShopCurrencyType { 12 | Cash(0), 13 | MaplePoint(1), 14 | Point(-1), 15 | Meso(-1); 16 | 17 | private final byte val; 18 | 19 | CashShopCurrencyType(int val) { 20 | this.val = (byte) val; 21 | } 22 | 23 | public byte getVal() { 24 | return val; 25 | } 26 | 27 | public static CashShopCurrencyType getByVal(byte type) { 28 | return Arrays.stream(values()).filter(v -> v.getVal() == type).findFirst().orElse(null); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/CharPotGrade.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum CharPotGrade { 5 | Rare, 6 | Epic, 7 | Unique, 8 | Legendary 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ChatRoomType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 1/12 20:41 10 | */ 11 | public enum ChatRoomType { 12 | Req_Join(0), 13 | Req_Leave(2), 14 | Res_ChatInviteRequest(3), 15 | Res_ChatInviteTip(4), 16 | Res_ChatInviteRefuseTip(5), 17 | Req_Chat(6), 18 | 19 | ; 20 | 21 | private final byte val; 22 | 23 | ChatRoomType(int val) { 24 | this.val = (byte) val; 25 | } 26 | 27 | public static ChatRoomType getByVal(byte val) { 28 | return Arrays.stream(values()).filter(mrt -> mrt.getVal() == val).findAny().orElse(null); 29 | } 30 | 31 | public byte getVal() { 32 | return val; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ChatType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | public enum ChatType { 6 | Normal(0), 7 | Whisper(1), 8 | GroupParty(2), 9 | GroupFriend(3), 10 | GroupGuild(4), 11 | GroupAlliance(5), 12 | GameDesc(6), 13 | Tip(7), 14 | Notice(8), 15 | Notice2(9), 16 | AdminChat(10), 17 | SystemNotice(11), 18 | SpeakerChannel(12), 19 | SpeakerWorld(13), 20 | SpeakerWorldGuildSkill(14), 21 | ItemSpeaker(15), 22 | ItemSpeakerItem(16), 23 | SpeakerBridge(17), 24 | SpeakerWorldExPreview(18), 25 | Mob(19), 26 | Expedition(20), 27 | ItemMessage(21), 28 | MiracleTime(22), 29 | LotteryItemSpeaker(23), 30 | YellowBlue(24), //[Lucid] : content 31 | AvatarMegaphone(25), 32 | PickupSpeakerWorld(26), 33 | WorldName(27), 34 | BossArenaNotice(28), 35 | Claim(29), 36 | Purple(30), 37 | BlackOnOrigin(33), 38 | Message(34), 39 | LoveSpeaker(36), 40 | MobileSpeaker(37), 41 | WhiteOnGreen(38), 42 | YellowOnRed(39), 43 | YellowOnRedChannel(39), 44 | CakeSpeaker(41), 45 | PieSpeaker(42), 46 | BlackOnGreen(43), 47 | BlackOnRed(44), 48 | BlackOnYellow(45), 49 | DarkBlue(46), 50 | BlackOnGreen2(47); 51 | 52 | private final short val; 53 | 54 | ChatType(short val) { 55 | this.val = val; 56 | } 57 | 58 | ChatType(int i) { 59 | this((short) i); 60 | } 61 | 62 | public short getVal() { 63 | return val; 64 | } 65 | 66 | public static ChatType getByVal(int type) { 67 | return Arrays.stream(values()).filter(bp -> bp.getVal() == type).findAny().orElse(null); 68 | } 69 | 70 | 71 | @Override 72 | public String toString() { 73 | return super.toString(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ClockType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum ClockType { 5 | EventTimer(0), 6 | HMSClock(1), 7 | SecondsClock(2), 8 | FromDefault(3), 9 | TimerGauge(4), 10 | ShiftTimer(5), 11 | StopWatch(6), 12 | PauseTimer(7), 13 | TimerInfoEx(8), 14 | WithoutField(9); 15 | 16 | private final byte val; 17 | 18 | ClockType(int val) { 19 | this.val = (byte) val; 20 | } 21 | 22 | public byte getVal() { 23 | return val; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/Command.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author fair 9 | * @version V1.0 10 | * @Package im.cave.ms.enums 11 | * @date 1/20 9:48 12 | */ 13 | public enum Command { 14 | SPAWN(0, 1), 15 | WARP(0, 1), 16 | JOB(0, 1), 17 | GAIN(0, 1), 18 | DROP(0, 1), 19 | CHANGE(0, 1), 20 | RELOAD(0, 1), 21 | KILL(0, 1), 22 | EA(0, 0), 23 | NPC(0, 0), 24 | HELP(0, 0), 25 | FAMILIAR(30, 0), 26 | SAVE(0, 0), 27 | EMS(10, 0); 28 | private final int reqLev; 29 | private final int reqGm; 30 | 31 | Command(int reqLev, int reqGm) { 32 | this.reqLev = reqLev; 33 | this.reqGm = reqGm; 34 | } 35 | 36 | public int getReqLev() { 37 | return reqLev; 38 | } 39 | 40 | public int getReqGm() { 41 | return reqGm; 42 | } 43 | 44 | public static Command getByName(String cmd) { 45 | return Util.findWithPred(values(), command -> command.name().equalsIgnoreCase(cmd)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/DamageSkinType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | public enum DamageSkinType { 4 | DamageSkinSaveReq_Reg(0), 5 | DamageSkinSaveReq_Remove(1), 6 | DamageSkinSaveReq_Active(2), 7 | DamageSkinSaveReq_SendInfo(3), 8 | DamageSkinSave_Success(4), 9 | DamageSkinSave_Fail_Unknown(5), 10 | DamageSkinSave_Fail_SlotCount(6), 11 | DamageSkinSave_Fail_AlreadyExist(7), 12 | DamageSkinSave_Fail_NotSave(8), 13 | DamageSkinSave_Fail_ServerValueBlock(9), 14 | DamageSkinSave_Fail_AlreadyActive(10), 15 | ; 16 | 17 | private final int val; 18 | 19 | DamageSkinType(int val) { 20 | this.val = val; 21 | } 22 | 23 | public int getVal() { 24 | return val; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/DropEnterType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum DropEnterType { 5 | Default(0), 6 | Floating(1), 7 | Instant(2), 8 | FadeAway(3); 9 | 10 | private final byte val; 11 | 12 | DropEnterType(int val) { 13 | this.val = (byte) val; 14 | } 15 | 16 | public byte getVal() { 17 | return val; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/DropLeaveType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum DropLeaveType { 5 | Fade(0), 6 | NoFade(1), 7 | CharPickup1(2), 8 | CharPickup2(3), 9 | DelayedPickup(4), 10 | PetPickup(5), 11 | Fade2(6), 12 | Absorb(7); // CAnimationDisplayer::RegisterAbsorbItemAnimationJP ? 13 | 14 | private final byte val; 15 | 16 | DropLeaveType(int val) { 17 | this.val = (byte) val; 18 | } 19 | 20 | public byte getVal() { 21 | return val; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/DropTimeoutStrategy.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.security.acl.Owner; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 2/24 19:34 10 | */ 11 | public enum DropTimeoutStrategy { 12 | TimeoutForNonOwner(0), 13 | TimeoutForNonOwnerParty(1), 14 | FFA(2), //无所有权 15 | Explosive(3); 16 | 17 | private byte val; 18 | 19 | DropTimeoutStrategy(int val) { 20 | this.val = (byte) val; 21 | } 22 | 23 | public byte getVal() { 24 | return val; 25 | } 26 | 27 | public void setVal(byte val) { 28 | this.val = val; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/EnterType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum EnterType { 5 | NoAnimation(0), 6 | Animation(1); 7 | 8 | private final byte val; 9 | 10 | EnterType(int val) { 11 | this.val = (byte) val; 12 | } 13 | 14 | public byte getVal() { 15 | return val; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/EquipAttribute.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum EquipAttribute { 5 | Locked(0x1), 6 | PreventSlipping(0x2), 7 | PreventColdness(0x4), 8 | Untradable(0x8), 9 | UntradableAfterTransaction(0x10), 10 | NoNonCombatStatGain(0x20), 11 | 12 | Crafted(0x80), 13 | ProtectionScroll(0x100), 14 | LuckyDay(0x200), 15 | 16 | TradedOnceWithinAccount(0x1000), 17 | UpgradeCountProtection(0x2000), 18 | ScrollProtection(0x4000), 19 | ReturnScroll(0x8000); 20 | 21 | private final int val; 22 | 23 | EquipAttribute(int val) { 24 | this.val = val; 25 | } 26 | 27 | public int getVal() { 28 | return val; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/EquipBaseStat.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum EquipBaseStat { 5 | tuc(0x1, 0), 6 | cuc(0x2, 0), 7 | iStr(0x4, 0), 8 | iDex(0x8, 0), 9 | iInt(0x10, 0), 10 | iLuk(0x20, 0), 11 | iMaxHP(0x40, 0), 12 | iMaxMP(0x80, 0), 13 | iPAD(0x100, 0), 14 | iMAD(0x200, 0), 15 | iPDD(0x400, 0), 16 | iMDD(0x800, 0), 17 | iACC(0x1000, 0), 18 | iEVA(0x2000, 0), 19 | iCraft(0x4000, 0), 20 | iSpeed(0x8000, 0), 21 | iJump(0x10000, 0), 22 | attribute(0x20000, 0), 23 | levelUpType(0x40000, 0), 24 | level(0x80000, 0), 25 | exp(0x100000, 0), 26 | durability(0x200000, 0), 27 | iuc(0x400000, 0), 28 | iPvpDamage(0x800000, 0), 29 | iReduceReq(0x1000000, 0), 30 | specialAttribute(0x2000000, 0), 31 | durabilityMax(0x4000000, 0), 32 | iIncReq(0x8000000, 0), 33 | growthEnchant(0x10000000, 0), 34 | psEnchant(0x20000000, 0), 35 | bdr(0x40000000, 0), 36 | imdr(0x80000000, 0), 37 | damR(0x1, 1), 38 | statR(0x2, 1), 39 | cuttable(0x4, 1), //1 40 | flame(0x8, 1), 41 | itemState(0x10, 1); //3 42 | 43 | private final int val; 44 | private final int pos; 45 | 46 | EquipBaseStat(int val, int pos) { 47 | this.val = val; 48 | this.pos = pos; 49 | } 50 | 51 | public int getVal() { 52 | return val; 53 | } 54 | 55 | public int getPos() { 56 | return pos; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/EquipSpecialAttribute.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum EquipSpecialAttribute { 5 | NotDestroy(0x1), 6 | GradeUpgrade(0x2), 7 | EnchantSuccess(0x4), // scroll always succeed 8 | Extended(0x8), 9 | OneMeso(0x10), 10 | MakingSkillMeister(0x20), 11 | MakingSkillMaster(0x40), 12 | Vestige(0x80), 13 | VestigeBound(0x200), 14 | VestigePossibleTrading(0x400), 15 | VestigeAppliedAccountShare(0x800); 16 | 17 | private final int val; 18 | 19 | EquipSpecialAttribute(int val) { 20 | this.val = val; 21 | } 22 | 23 | public int getVal() { 24 | return val; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/EquipmentEnchantType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | public enum EquipmentEnchantType { 6 | ScrollUpgradeRequest(0), 7 | HyperUpgradeRequest(1), 8 | TransmissionResult(2), 9 | ScrollUpgradeDisplay(50), 10 | ScrollTimerEffective(51), 11 | HyperUpgradeDisplay(52), 12 | MiniGameDisplay(53), 13 | ShowScrollUpgradeResult(100), 14 | ShowHyperUpgradeResult(101), 15 | ShowScrollVestigeCompensationResult(102), 16 | ShowTransmissionResult(103), 17 | ShowUnknownFailResult(104), 18 | Unk(105); 19 | 20 | private final byte val; 21 | 22 | EquipmentEnchantType(int val) { 23 | this.val = (byte) val; 24 | } 25 | 26 | public static EquipmentEnchantType getByVal(byte val) { 27 | return Arrays.stream(values()).filter(tt -> tt.getVal() == val).findAny().orElse(null); 28 | } 29 | 30 | public byte getVal() { 31 | return val; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ExpIncreaseInfoFlags.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum ExpIncreaseInfoFlags { 5 | SelectedMobBonusExp(0x1), 6 | PartyBonusPercentage(0x4), 7 | PartyBonusExp(0x10), 8 | WeddingBonusExp(0x20), 9 | ItemBonusExp(0x40), 10 | PremiumIPBonusExp(0x80), 11 | RainbowWeekEventBonusExp(0x100), 12 | BoomUpEventBonusExp(0x200), 13 | PlusExpBuffBonusExp(0x400), 14 | PsdBonusExpRate(0x800), 15 | IndieBonusExp(0x1000), 16 | RelaxBonusExp(0x2000), 17 | InstallItemBonusExp(0x4000), 18 | AswanWinnerBonusExp(0x8000), 19 | ExpByIncExpR(0x10000), 20 | ValuePackBonusExp(0x20000), 21 | ExpByIncPQExpR(0x40000), 22 | BaseAddExp(0x80000), 23 | BloodAllianceBonusExp(0x100000), 24 | FreezeHotEventBonusExp(0x200000), 25 | RestField(0x400000), 26 | UserHPRateBonusExp(0x800000), 27 | FieldValueBonusExp(0x1000000), 28 | MobKillBonusExp(0x2000000), 29 | LiveEventBonusExp(0x4000000), 30 | Unk8000000(0x8000000), 31 | Unk10000000(0x10000000), 32 | Unk20000000(0x20000000), 33 | Unk40000000(0x40000000), 34 | Unk80000000(0x80000000), 35 | Unk1000000000(0x1000000000L); 36 | 37 | private long val; 38 | 39 | ExpIncreaseInfoFlags(long val) { 40 | this.val = val; 41 | } 42 | 43 | public long getVal() { 44 | return val; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ExpressAction.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 1/17 15:52 10 | */ 11 | public enum ExpressAction { 12 | Req_Load(1), 13 | Req_Send_Normal(3), 14 | Req_PickUp(5), 15 | Req_Drop(6), 16 | Req_Close_Dialog(8), 17 | Res_Open_Dialog(9), 18 | Res_Init_Locker(10), 19 | Res_Send_Success(11), 20 | Res_Please_Check_Name(14), 21 | Res_Send_Done(19), 22 | Res_Remove_Done(24), 23 | Res_New_Msg(26); 24 | 25 | 26 | private final byte val; 27 | 28 | ExpressAction(int val) { 29 | this.val = (byte) val; 30 | } 31 | 32 | 33 | public static ExpressAction getByVal(byte val) { 34 | return Arrays.stream(values()).filter(mrt -> mrt.getVal() == val).findAny().orElse(null); 35 | } 36 | 37 | public byte getVal() { 38 | return val; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/FameAction.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 3/25 9:01 8 | */ 9 | public enum FameAction { 10 | Add(0), 11 | AlreadyAddInThisMonth(4), 12 | Receive(5); 13 | 14 | 15 | private final byte val; 16 | 17 | FameAction(int val) { 18 | this.val = (byte) val; 19 | } 20 | 21 | public byte getVal() { 22 | return val; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/FamiliarGrade.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 2/20 14:51 8 | */ 9 | public enum FamiliarGrade { 10 | C, 11 | B, 12 | A, 13 | S, 14 | SS 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/FamiliarType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 1/18 21:17 8 | */ 9 | public enum FamiliarType { 10 | e1, 11 | e2, 12 | e3, 13 | e4, 14 | e5, 15 | e6, 16 | e7, 17 | e8, 18 | e9; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/FieldEffectType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum FieldEffectType { 5 | Summon(0), 6 | Tremble(1), 7 | ObjectStateByString(2), 8 | DisableEffectObject(3), 9 | Screen(4), 10 | PlaySound(5), 11 | MobHPTag(6), 12 | ChangeBGM(7), 13 | BGMVolumeOnly(8), 14 | SetBGMVolume(9), 15 | // 10 16 | // 11 17 | // 12 18 | // 13 19 | // 14 20 | RewardRoulette(15), 21 | TopScreen(16), 22 | BackScreen(17), 23 | TopScreenEffect(18), 24 | ScreenEffect(19), 25 | ScreenFloatingEffect(20), 26 | Blind(21), 27 | SetGrey(22), 28 | OnOffLayer(23), 29 | OverlapScreen(24), 30 | OverlapScreenDetail(25), 31 | RemoveOverlapScreen(26), 32 | ChangeColor(27), 33 | StageClearExpOnly(28), 34 | TopScreen_WithOrigin(29), 35 | SpineScreen(30), 36 | OffSpineScreen(31), 37 | 38 | 39 | ; 40 | 41 | private byte val; 42 | 43 | FieldEffectType(int val) { 44 | this.val = (byte) val; 45 | } 46 | 47 | public byte getVal() { 48 | return val; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/FieldOption.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | public enum FieldOption { 4 | MoveLimit(0x1L), 5 | SkillLimit(0x2L), 6 | SummonLimit(0x4L), 7 | MysticDoorLimit(0x8L), 8 | MigrateLimit(0x10L), 9 | PortalScrollLimit(0x20L), 10 | TeleportItemLimit(0x40L), 11 | MiniGameLimit(0x80L), 12 | SpecificPortalScrollLimit(0x100L), 13 | TamingMobLimit(0x200L), 14 | StatChangeItemConsumeLimit(0x400L), 15 | PartyBossChangeLimit(0x800L), 16 | NoMobCapacityLimit(0x1000L), 17 | WeddingInvitationLimit(0x2000L), 18 | CashWeatherConsumeLimit(0x4000L), 19 | NoPet(0x8000L), 20 | AntiMacroLimit(0x10000L), 21 | FallDownLimit(0x20000L), 22 | SummonNPCLimit(0x40000L), 23 | NoEXPDecrease(0x80000L), 24 | NoDamageOnFalling(0x100000L), 25 | ParcelOpenLimit(0x200000L), 26 | DropLimit(0x400000L), 27 | RocketBoosterLimit(0x800000L), 28 | ItemOptionLimit(0x1000000L), 29 | NoQuestAlertLimit(0x2000000L), 30 | NoAndroid(0x4000000L), 31 | AutoExpandMinimap(0x8000000L), 32 | MoveSkillOnly(0x10000000L), 33 | OnlyStarPlanetPet(0x20000000L); 34 | 35 | private long val; 36 | 37 | FieldOption(long val) { 38 | this.val = val; 39 | } 40 | 41 | public long getVal() { 42 | return val; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/FlameStat.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | import im.cave.ms.tools.Util; 5 | 6 | import java.util.Arrays; 7 | 8 | 9 | public enum FlameStat { 10 | STR(0), 11 | DEX(10), 12 | INT(20), 13 | LUK(30), 14 | STR_DEX(40), 15 | STR_INT(50), 16 | STR_LUK(60), 17 | DEX_INT(70), 18 | DEX_LUK(80), 19 | INT_LUK(90), 20 | MaxHP(100), 21 | MaxMP(110), 22 | LevelReduction(120), 23 | Defense(130), 24 | Attack(170), 25 | MagicAttack(180), 26 | Speed(190), 27 | Jump(200), 28 | BossDamage(210), 29 | Damage(230), 30 | AllStats(240); 31 | 32 | private final int val; 33 | 34 | FlameStat(int val) { 35 | this.val = val; 36 | } 37 | 38 | public static FlameStat getByVal(int val) { 39 | return Util.findWithPred(Arrays.asList(values()), stat -> stat.getVal() == val); 40 | } 41 | 42 | public static FlameStat getByOrdinal(int ordinal) { 43 | return Util.findWithPred(values(), flameStat -> flameStat.ordinal() == ordinal); 44 | } 45 | 46 | public int getVal() { 47 | return val; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/FriendFlag.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum FriendFlag { 5 | Friend(0), 6 | FriendRequest(1), 7 | FriendOffline(2), 8 | FriendOnline(3), 9 | MobileOnline(4), 10 | MobileOffline(5), // ? 11 | AccountFriendRequest(6), 12 | AccountFriendOnline(7), 13 | AccountFriendOffline(8), 14 | 15 | ; 16 | 17 | private int val; 18 | 19 | FriendFlag(int val) { 20 | this.val = val; 21 | } 22 | 23 | public int getVal() { 24 | return val; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/Gender.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 1/8 14:35 8 | */ 9 | public enum Gender { 10 | Male, 11 | Female, 12 | All; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/GreyFieldType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | public enum GreyFieldType { 4 | Field(0), 5 | Background(1), 6 | Platform(2), 7 | BackGroundObject(3), 8 | NPC(4), 9 | Player(5), 10 | Mob(6), 11 | Portal(7), 12 | Reactor(8), 13 | ; 14 | 15 | private final byte val; 16 | 17 | GreyFieldType(int val) {this.val = (byte) val;} 18 | 19 | public byte getVal() {return val;} 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/GuildOption.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 1/29 15:20 8 | */ 9 | public enum GuildOption { 10 | Trend_Harmony(0x01), 11 | Trend_DressUp(0x02), 12 | Trend_Hunting(0x04), 13 | Trend_Business(0x08), 14 | Trend_Collect(0x10), 15 | Trend_Professional(0x20), 16 | Trend_TeamGame(0x40), 17 | Trend_Boss(0x80), 18 | 19 | Time_Non_Weekend(0x01), 20 | Time_Weekend(0x02), 21 | Time_00_06(0x04), 22 | Time_06_12(0x08), 23 | Time_12_18(0x10), 24 | Time_18_24(0x20), 25 | 26 | Age_10th_Gen(0x01), 27 | Age_20th_Gen(0x02), 28 | Age_30th_Gen(0x04), 29 | Age_Other(0x08); 30 | 31 | 32 | private final int val; 33 | 34 | private GuildOption(int val) { 35 | this.val = val; 36 | } 37 | 38 | public int getVal() { 39 | return val; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/GuildRight.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 2/3 13:04 8 | *

9 | * 家族成员的权限 10 | *

11 | */ 12 | public enum GuildRight { 13 | ALL(0xFFFF), 14 | NULL(0), 15 | INVITE(0x1), 16 | EDIT_NOTICE(0x2), 17 | CHANGE_GRADE(0x4), 18 | EDIT_MARK(0x8), 19 | KICK(0x10), 20 | BULLETIN_BOARD_MANAGE(0x20), 21 | VERIFY_APPLY(0x40), 22 | GUILD_SKILL_MANAGE(0x100), 23 | USE_GUILD_SKILL(0x400), 24 | WATERWAY_MANAGE(0x4000), 25 | ; 26 | 27 | 28 | private int val; 29 | 30 | GuildRight(int val) { 31 | this.val = val; 32 | } 33 | 34 | public int getVal() { 35 | return val; 36 | } 37 | 38 | public void setVal(int val) { 39 | this.val = val; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/HotTimeRewardResultType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 1/20 11:15 8 | */ 9 | public enum HotTimeRewardResultType { 10 | LIST(0xD5), 11 | GET_MAPLE_POINT(0xD7), 12 | GET_ITEM(0xD8); 13 | 14 | private final byte val; 15 | 16 | HotTimeRewardResultType(int val) { 17 | this.val = (byte) val; 18 | } 19 | 20 | public byte getVal() { 21 | return val; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/InGameDirectionEventType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum InGameDirectionEventType { 5 | ForcedAction(0), 6 | Delay(1), 7 | EffectPlay(2), 8 | ForcedInput(3), 9 | PatternInputRequest(4), 10 | CameraMove(5),// automated send delay 11 | CameraOnCharacter(6), 12 | CameraZoom(7),// automated send delay 13 | CameraReleaseFromUserPoint(8), 14 | VansheeMode(9), 15 | FaceOff(10), 16 | Monologue(11), 17 | MonologueScroll(12), 18 | AvatarLookSet(13), 19 | RemoveAdditionalEffect(14), 20 | // 15 21 | ForcedMove(16), 22 | ForcedFlip(17), 23 | InputUI(18), 24 | // 19 25 | // 20 26 | // 21 27 | // 22 28 | ; 29 | 30 | private int val; 31 | 32 | InGameDirectionEventType(int val) { 33 | this.val = val; 34 | } 35 | 36 | public int getVal() { 37 | return val; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/InstanceTableType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | import java.util.Arrays; 6 | 7 | 8 | public enum InstanceTableType { 9 | 10 | HyperPassiveSkill("hyper", 28, 0), 11 | HyperActiveSkill("hyper", 28, 1), 12 | HyperStatIncAmount("incHyperStat", 0, 0), 13 | NeedHyperStatLv("needHyperStatLv", 0, 0), 14 | Skill_9200("92000000", 0, 0), 15 | Skill_9201("92010000", 0, 0), 16 | Skill_9202("92020000", 0, 0), 17 | Skill_9203("92030000", 0, 0), 18 | Skill_9204("92040000", 0, 0), 19 | ; 20 | 21 | private final String tableName; 22 | private final int type; 23 | private final int subType; 24 | 25 | InstanceTableType(String tableName, int type, int subType) { 26 | this.tableName = tableName; 27 | this.type = type; 28 | this.subType = subType; 29 | } 30 | 31 | public static InstanceTableType getByStr(String requestStr) { 32 | return Util.findWithPred(Arrays.asList(values()), itt -> itt.getTableName().equals(requestStr)); 33 | } 34 | 35 | public String getTableName() { 36 | return tableName; 37 | } 38 | 39 | public int getType() { 40 | return type; 41 | } 42 | 43 | public int getSubType() { 44 | return subType; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/InventoryOperationType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum InventoryOperationType { 5 | ADD(0), 6 | UPDATE_QUANTITY(1), 7 | MOVE(2), 8 | REMOVE(3), 9 | ITEM_EXP(4), 10 | UPDATE_BAG_POS(5), 11 | UPDATE_BAG_QUANTITY(6), 12 | UNK_1(7), 13 | UPDATE_ITEM_INFO(9), 14 | UNK_2(9), 15 | UNK_3(10), 16 | ; 17 | 18 | private final byte val; 19 | 20 | InventoryOperationType(int val) { 21 | this.val = (byte) val; 22 | } 23 | 24 | public byte getVal() { 25 | return val; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ItemOptionType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | import java.util.Arrays; 6 | 7 | 8 | public enum ItemOptionType { 9 | AnyEquip(0), 10 | Weapon(10), 11 | AnyExceptWeapon(11), 12 | ArmorExceptGlove(20), 13 | Accessory(40), 14 | Hat(51), 15 | Top(52), 16 | Bottom(53), 17 | Glove(54), 18 | Shoes(55); 19 | 20 | private int val; 21 | 22 | ItemOptionType(int val) { 23 | this.val = val; 24 | } 25 | 26 | public static ItemOptionType getByVal(int val) { 27 | return Util.findWithPred(Arrays.asList(values()), stat -> stat.getVal() == val); 28 | } 29 | 30 | public int getVal() { 31 | return val; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ItemState.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum ItemState { 5 | MiraculousEnhancement(0x1), 6 | RefundableGachaponItem(0x8), 7 | RefundableEventGachaponItem(0x10), 8 | RedLabelItem(0x20), 9 | BlackLabelItem(0x40), 10 | InnocentRUCItem(0x80), 11 | AmazingHyperUpgradeChecked(0x100), 12 | AmazingHyperUpgradeUsed_Log(0x200), 13 | AmazingHyperUpgradeUsed_Stat(0x400), 14 | AmazingHyperUpgradeUsed_Sync(0x800); 15 | 16 | private int val; 17 | 18 | ItemState(int val) { 19 | this.val = val; 20 | } 21 | 22 | public int getVal() { 23 | return val; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/LoginStatus.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 11/19 17:29 8 | */ 9 | public enum LoginStatus { 10 | NOTLOGGEDIN, 11 | SERVER_TRANSITION, 12 | LOGGEDIN; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/MapTransferType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | 6 | public enum MapTransferType { 7 | DeleteListRecv(0), 8 | RegisterListRecv(1), 9 | DeleteListSend(2), 10 | RegisterListSend(3), 11 | Use(4), 12 | Unknown(5), 13 | TargetNotExist(6), 14 | TargetDied(7), 15 | NotAllowed(8), 16 | AlreadyInMap(9), 17 | RegisterFail(10), 18 | NotAllowedForVariousReason(11); 19 | 20 | private final byte val; 21 | 22 | MapTransferType(int val) { 23 | this.val = (byte) val; 24 | } 25 | 26 | public static MapTransferType getByVal(byte val) { 27 | return Arrays.stream(values()).filter(mtt -> mtt.getVal() == val).findAny().orElse(null); 28 | } 29 | 30 | public byte getVal() { 31 | return val; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/MapleNotesType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 1/12 22:06 10 | */ 11 | public enum MapleNotesType { 12 | Req_Send(0), 13 | Req_Delete_Received_Notes(2), 14 | Req_Delete_Sent_Notes(3), 15 | Req_Read(5), 16 | Res_Inbox(6), 17 | Res_Outbox(7), 18 | Res_Send_Success(8), 19 | Res_Send_Fail(9), 20 | Res_Delete_Received_Success(11), 21 | Res_Delete_Sent_Success(13), 22 | Res_InNotes_Read(14), 23 | Res_Add_Sent(15), 24 | ; 25 | 26 | private final byte val; 27 | 28 | MapleNotesType(int val) { 29 | this.val = (byte) val; 30 | } 31 | 32 | public byte getVal() { 33 | return val; 34 | } 35 | 36 | public static MapleNotesType getByVal(byte val) { 37 | return Arrays.stream(values()).filter(mrt -> mrt.getVal() == val).findAny().orElse(null); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/MatrixStateType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | public enum MatrixStateType { 6 | DISASSEMBLED(0), INACTIVE(1), ACTIVE(2); 7 | private final int val; 8 | 9 | MatrixStateType(int val) { 10 | this.val = val; 11 | } 12 | 13 | public int getVal() { 14 | return val; 15 | } 16 | 17 | public static MatrixStateType getStateByVal(int val) { 18 | return Arrays.stream(values()).filter(vst -> vst.getVal() == val).findAny().orElse(null); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/MatrixUpdateType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | public enum MatrixUpdateType { 6 | ENABLE(0), 7 | DISABLE(1), 8 | MOVE(2), 9 | //3 10 | ENHANCE(4), 11 | DISASSEMBLE_SINGLE(5), 12 | DISASSEMBLE_MULTIPLE(6), 13 | CRAFT_NODE(7), 14 | //8 15 | CRAFT_NODESTONE(9), 16 | SLOT_ENHANCEMENT(10), 17 | //1 18 | RESET_SLOT_ENHANCEMENT(12); 19 | 20 | private final int val; 21 | 22 | MatrixUpdateType(int val) { 23 | this.val = val; 24 | } 25 | 26 | public int getVal() { 27 | return val; 28 | } 29 | 30 | public static MatrixUpdateType getUpdateTypeByVal(int val) { 31 | return Arrays.stream(values()).filter(vut -> vut.getVal() == val).findAny().orElse(null); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/MiniRoomType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | public enum MiniRoomType { 6 | PlaceItem(0), 7 | PlaceItem_2(1), 8 | PlaceItem_3(2), 9 | PlaceItem_4(3), 10 | 11 | SetMesos(4), 12 | SetMesos_2(5), 13 | SetMesos_3(6), 14 | SetMesos_4(7), 15 | Trade(8), 16 | TradeConfirm(9), 17 | TradeConfirm2(10), 18 | TradeConfirm3(11), // 3...? 19 | TradeConfirmRemoteResponse(14), // what is this even used for 20 | 21 | TradeRestraintItem(15), 22 | Create(16), 23 | Accept(19), 24 | EnterTrade(20), 25 | TradeInviteRequest(21), 26 | InviteResultStatic(22), 27 | 28 | Chat(24), 29 | 五子棋和及一大考验(26), //01 30 | Avatar(27), 31 | ExitTrade(28), 32 | 33 | CheckSSN2(30), 34 | Ready(94), 35 | UnReady(95), 36 | Start(97), //发起方 1bit 对方2bit 01 37 | RPSSelect(98), //2剪刀 0 拳头 1布 38 | RPSInvite(113), 39 | RPSResult(114), //0 赢 1 平 2 输 + 对方的选择 40 | ; 41 | 42 | private final byte val; 43 | 44 | MiniRoomType(int val) { 45 | this.val = (byte) val; 46 | } 47 | 48 | public static MiniRoomType getByVal(byte val) { 49 | return Arrays.stream(values()).filter(mrt -> mrt.getVal() == val).findAny().orElse(null); 50 | } 51 | 52 | public byte getVal() { 53 | return val; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/MobSkillStat.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum MobSkillStat { 5 | x, 6 | mpCon, 7 | interval, 8 | time, 9 | hp, 10 | info, 11 | y, 12 | zero, 13 | limit, 14 | broadCastScreenMsg, 15 | w, 16 | z, 17 | parsing, 18 | prop, 19 | ignoreResist, 20 | targetAggro, 21 | fieldScript, 22 | elemAttr, 23 | delay, 24 | rank, 25 | HPDeltaR, 26 | summonEffect, 27 | y2, 28 | q, 29 | q2, 30 | s2, 31 | u, 32 | u2, 33 | v, 34 | z2, 35 | w2, 36 | skillAfter, 37 | x2, 38 | script, 39 | attackSuccessProp, 40 | bossHeal, 41 | face, 42 | callSkill, 43 | level, 44 | linkHP, 45 | timeLimitedExchange, 46 | summonDir, 47 | summonTerm, 48 | castingTime, 49 | subTime, 50 | reduceCasting, 51 | additionalTime, 52 | notDestroyByCollide, 53 | noGravity, 54 | rangeGap, 55 | sideAttack, 56 | forcex, 57 | targetType, 58 | force, 59 | count 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/MoveAbility.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum MoveAbility { 5 | Stop(0), 6 | Walk(1), 7 | WalkRandom(2), 8 | Fly(3), 9 | FlyRandom(4), 10 | Smart(5), 11 | FixVMove(6), 12 | WalkSmart(7), 13 | WalkClone(8), 14 | FlyClone(9), 15 | WalkHang(10), 16 | Jaguar(11), 17 | FlyJaguar(12), 18 | 19 | ; 20 | 21 | private byte val; 22 | 23 | MoveAbility(int val) { 24 | this.val = (byte) val; 25 | } 26 | 27 | public byte getVal() { 28 | return val; 29 | } 30 | 31 | public boolean changeFieldWithOwner() { 32 | return this != Stop; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ObstacleAtomCreateType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * Created on 5/30/2018. 5 | */ 6 | public enum ObstacleAtomCreateType { 7 | NORMAL(0), 8 | IN_ROW(1), 9 | TORNADO(2), 10 | MOB_SKILL(3), 11 | RADIAL(4), 12 | DIAGONAL(5), 13 | FIXED_POS(6), 14 | // NO, seems to indicate end 15 | ; 16 | 17 | private final byte val; 18 | 19 | ObstacleAtomCreateType(int val) { 20 | this.val = (byte) val; 21 | } 22 | 23 | public byte getVal() { 24 | return val; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/PartyQuestType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * 组队任务类型/组队BOSS 5 | * 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 2/25 9:50 10 | */ 11 | public enum PartyQuestType { 12 | Party1, 13 | Party2, 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/PetSkill.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * Created on 4/20/2018. 5 | */ 6 | public enum PetSkill { 7 | ITEM_PICKUP(0x1), //捡起道具 8 | EXPANDED_AUTO_MOVE(0x2), 9 | AUTO_MOVE(0x4), //范围自动捡取 10 | IGNORE_ITEM(0x8), //排除道具 11 | EXPIRED_PICKUP(0x10), //捡起无所有权 12 | AUTO_HP(0x20), 13 | AUTO_MP(0x40), 14 | RECALL(0x80), //宠物召回 15 | AUTO_SPEAKING(0x100), //自言自语 16 | AUTO_BUFF(0x200), 17 | PET_SHOP(0x400), //不知道 18 | AUTO_FEED(0x800), 19 | FATTEN_UP(0x1000), //巨大化 20 | 21 | ; 22 | 23 | private final int val; 24 | 25 | public int getVal() { 26 | return val; 27 | } 28 | 29 | PetSkill(int val) { 30 | this.val = val; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/PortalType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.constant 9 | * @date 11/27 11:39 10 | */ 11 | public enum PortalType { 12 | StartPoint(0), 13 | PortalInvisible(1), 14 | PortalVisible(2), 15 | PortalCollision(3), 16 | PortalChangable(4), 17 | PortalChangableInvisible(5), 18 | TownPortalPoint(6), 19 | PortalScript(7), 20 | PortalScriptInvisible(8), 21 | PortalCollisionScript(9), 22 | PortalHidden(10), 23 | PortalScriptHidden(11), 24 | PortalCollisionJump(12), 25 | PortalCollisionCustom(13), 26 | PortalCollisionInvisibleChangable(14), // ? 27 | PortalUnk(15), // ? On map ID 910800200 28 | ; 29 | private final byte val; 30 | 31 | PortalType(byte val) { 32 | this.val = val; 33 | } 34 | 35 | PortalType(int val) { 36 | this((byte) val); 37 | } 38 | 39 | public byte getVal() { 40 | return val; 41 | } 42 | 43 | public static PortalType getTypeByInt(int i) { 44 | return Arrays.stream(values()).filter(p -> p.getVal() == i).findFirst().orElse(null); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/PrivateStatusIDFlag.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Created by MechAviv on 2/22/2019. 7 | */ 8 | public enum PrivateStatusIDFlag { 9 | NONE(0x0), 10 | // Customs: 11 | ADMIN(0x14),// ADMIN_CLIENT | MANAGER_ACCOUNT 12 | GAME_MASTER(0x15),// PRIMARY_TRACE | ADMIN_CLIENT | MANAGER_ACCOUNT 13 | TESTER(0x25),// PRIMARY_TRACE | TESTER_ACCOUNT | MANAGER_ACCOUNT 14 | 15 | //~~~~~~~~~~~~~~~~~~~ 16 | PRIMARY_TRACE(0x1), 17 | MESO_TRACE(0x2), 18 | ADMIN_CLIENT(0x4), 19 | MOB_MOVE_OBSERVE(0x8), 20 | MANAGER_ACCOUNT(0x10), 21 | TESTER_ACCOUNT(0x20), 22 | SECONDARY_TRACE(0x40), 23 | MACRO_WORKING(0x80), 24 | NOT_ACTIVE_ACCOUNT(0x100), 25 | MACRO_RECEIVER_1(0x200), 26 | MACRO_RECEIVER_2(0x400), 27 | MACRO_RECEIVER_3(0x800), 28 | MACRO_RECEIVER_4(0x1000), 29 | SUB_TESTER_ACCOUNT(0x2000), 30 | PROTECT_ACCOUNT(0x4000), 31 | STAR_PLANET_M_TRACE(0x8000); 32 | 33 | private int flag; 34 | 35 | PrivateStatusIDFlag(int flag) { 36 | this.flag = flag; 37 | } 38 | 39 | public int getFlag() { 40 | return flag; 41 | } 42 | 43 | public boolean hasFlag(PrivateStatusIDFlag psFlag) { 44 | return (getFlag() & psFlag.getFlag()) != 0; 45 | } 46 | 47 | public static PrivateStatusIDFlag getStatusByFlag(int flag) { 48 | return Arrays.stream(values()).filter(f -> f.getFlag() == flag).findAny().orElse(null); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/QuestStatus.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 11/27 20:46 8 | */ 9 | public enum QuestStatus { 10 | NotStarted(0), 11 | Started(1), 12 | Completed(2); 13 | 14 | private final byte val; 15 | 16 | QuestStatus(int val) { 17 | this.val = (byte) val; 18 | } 19 | 20 | public byte getVal() { 21 | return val; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/QuestType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | 6 | public enum QuestType { 7 | QuestReq_LostItem(0), 8 | QuestReq_AcceptQuest(1), 9 | QuestReq_CompleteQuest(2), 10 | QuestReq_ResignQuest(3), 11 | QuestReq_OpeningScript(4), 12 | QuestReq_CompleteScript(5), 13 | QuestReq_LaterStep(6), 14 | 15 | QuestRes_Start_QuestTimer(7), 16 | QuestRes_End_QuestTimer(8), 17 | QuestRes_Start_TimeKeepQuestTimer(9), 18 | QuestRes_End_TimeKeepQuestTimer(10), 19 | QuestRes_Act_Success(11), 20 | QuestRes_Act_Failed_Unknown(12), 21 | QuestRes_Act_Failed_Inventory(13), 22 | QuestRes_Act_Failed_Meso(14), 23 | QuestRes_Act_Failed_OverflowMeso(15), 24 | QuestRes_Act_Failed_Pet(16), 25 | QuestRes_Act_Failed_Equipped(17), 26 | QuestRes_Act_Failed_OnlyItem(18), 27 | QuestRes_Act_Failed_TimeOver(19), 28 | QuestRes_Act_Failed_State(20), 29 | QuestRes_Act_Failed_Quest(21), 30 | QuestRes_Act_Failed_Block(22), 31 | QuestRes_Act_Failed_Universe(23), 32 | QuestRes_Act_Reset_QuestTimer(24), 33 | MakingRes_Success_SoSo(25), 34 | MakingRes_Success_Good(26), 35 | MakingRes_Success_Cool(27), 36 | MakingRes_Fail_Unknown(28), 37 | MakingRes_Fail_Prob(29), 38 | MakingRes_Fail_NoDecomposer(30), 39 | MakingRes_Fail_MesoOverflow(31), 40 | MakingRes_Fail_TooHighFee(32), 41 | MakingRes_Fail_NotEnoughMeso(33), 42 | ; 43 | 44 | private final byte val; 45 | 46 | QuestType(int val) { 47 | this.val = (byte) val; 48 | } 49 | 50 | public byte getVal() { 51 | return val; 52 | } 53 | 54 | public static QuestType getType(byte type) { 55 | return Arrays.stream(values()).filter(qt -> qt.getVal() == type).findAny().orElse(null); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/QuickMoveType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum QuickMoveType { 5 | Gladiator(0), 6 | MonsterPark(1), 7 | DimensionalPortal(2), 8 | FreeMarket(3), 9 | Ardentmill(4), 10 | Boat(5), 11 | Taxi(6), 12 | Baret(7), 13 | Cat(8), 14 | Dojo(9), 15 | SpinningGlasses(10), //打工 16 | BlueKnightOfCygnusWoman(11), 17 | BlueKnightOfCygnusMan(12), 18 | BigHeadward(13), 19 | Nurse(14), 20 | PinkKnightOfCygnusWoman(15), 21 | PinkKnightOfCygnusMan(16), 22 | Waitress(17), 23 | Bunny(18), 24 | Girl(19), 25 | Announcer(20), 26 | MobileWoman(21), 27 | Hera(104), 28 | Party(105) 29 | 30 | ; 31 | private final int val; 32 | 33 | QuickMoveType(int val) { 34 | this.val = val; 35 | } 36 | 37 | public int getVal() { 38 | return val; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/RecordType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 1/7 17:04 10 | */ 11 | public enum RecordType { 12 | PARTY_QUEST_LOG, 13 | BOSS_LOG, 14 | RETURN_MAP, 15 | MAP_ENTER, 16 | NPC_TALK_COUNT(true); 17 | 18 | private boolean transition; 19 | 20 | RecordType(boolean transition) { 21 | this.transition = transition; 22 | } 23 | 24 | RecordType() { 25 | } 26 | 27 | public static RecordType getByName(String name) { 28 | return Util.findWithPred(values(), type -> type.name().equals(name)); 29 | } 30 | 31 | public boolean isTransition() { 32 | return transition; 33 | } 34 | 35 | public void setTransition(boolean transition) { 36 | this.transition = transition; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/RemoveMobType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum RemoveMobType { 5 | STAY(0), 6 | ANIMATION_DEATH(1), 7 | NO_ANIMATION_DEATH(2), 8 | INSTA_DEATH(3), 9 | NO_ANIMATION_DEATH_2(4), 10 | ANIMATION_DEATH_2(5), 11 | ANIMATION_DEATH_3(6), 12 | 13 | ; 14 | private final byte val; 15 | 16 | RemoveMobType(byte val) { 17 | this.val = val; 18 | } 19 | 20 | RemoveMobType(int val) { 21 | this((byte) val); 22 | } 23 | 24 | public byte getVal() { 25 | return val; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/RequiredJob.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum RequiredJob { 5 | Beginner(-1), 6 | AnyJob(0), 7 | Warrior(0x1), 8 | Magician(0x2), 9 | Bowman(0x4), 10 | Thief(0x8), 11 | Pirate(0x10); 12 | 13 | private int val; 14 | 15 | RequiredJob(int val) { 16 | this.val = val; 17 | } 18 | 19 | public int getVal() { 20 | return val; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/RoomLeaveType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum RoomLeaveType { 5 | MRLeave_UserRequest(0), 6 | MRLeave_WrongPosition(1), 7 | MRLeave_Closed(2), 8 | MRLeave_HostOut(3), 9 | MRLeave_Booked(4), 10 | MRLeave_Kicked(5), 11 | MRLeave_OpenTimeOver(6), 12 | TRLeave_TradeDone(7), 13 | TRLeave_TradeFail(8), 14 | TRLeave_TradeFail_OnlyItem(9), 15 | TRLeave_TradeFail_Expired(10), 16 | TRLeave_TradeFail_Denied(11), 17 | TRLeave_TradeFail_Invalid_CashItemSN(12), 18 | TRLeave_FieldError(13), 19 | TRLeave_ItemCRCFailed(14), 20 | TRLeave_Trade_UnableWorld(15), 21 | PSLeave_NoMoreItem(16), 22 | PSLeave_KickedTimeOver(17), 23 | ESLeave_Open(18), 24 | ESLeave_StartManage(19), 25 | ESLeave_ClosedTimeOver(20), 26 | ESLeave_EndManage(21), 27 | ESLeave_DestoryByAdmin(22), 28 | MGLeave_UserRequest(23), 29 | WRLeave_PartnerGone(24), 30 | WRLeave_CanceledByNoInventory0(25), 31 | WRLeave_CanceledByNoInventory1(26), 32 | WRLeave_GracefulClose(27), 33 | CMRLeave_NoCandy(28), 34 | CMRLeave_NoHostInven(29), 35 | CMRLeave_NoGuestInven(30), 36 | CMRLeave_Reject(31), 37 | CMRLeave_NotOnTime(32), 38 | CMRLeave_Done(33), 39 | CMRLeave_Failed(34), 40 | ; 41 | 42 | private int val; 43 | 44 | RoomLeaveType(int val) { 45 | this.val = val; 46 | } 47 | 48 | public int getVal() { 49 | return val; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ServerType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.enums 7 | * @date 11/19 19:13 8 | */ 9 | public enum ServerType { 10 | LOGIN, WORLD, CHANNEL, CASHSHOP, CHAT, AUCTION 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ShopRequestType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | 6 | public enum ShopRequestType { 7 | BUY(0), 8 | SELL(1), 9 | RECHARGE(2), 10 | CLOSE(3), 11 | ; 12 | 13 | private int val; 14 | 15 | ShopRequestType(int val) { 16 | this.val = val; 17 | } 18 | 19 | public static ShopRequestType getByVal(byte type) { 20 | return Arrays.stream(values()).filter(v -> v.getVal() == type).findFirst().orElse(null); 21 | } 22 | 23 | public int getVal() { 24 | return val; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/ShopResultType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | public enum ShopResultType { 4 | Buy(0), 5 | NotEnoughInStockMsg(1), 6 | NotEnoughMesosMsg(2), 7 | NotEnoughPointsMsg(3), 8 | RequireFloorEnterMsg(4), // int 9 | DoNotMeetReqsMsg(5), 10 | CannotBePurchasedRnMsg(6), 11 | FullInvMsg(10), 12 | SellResult(11), 13 | RechargeSuccess(17), 14 | PlayerNotEnoughInStockMsg(9), 15 | GeneralErrorMsg(10), 16 | TooManyMesosMsg(11), 17 | MesoCapPerTransaction2mMsg(12), 18 | CannotHoldMoreMesosMsg(13), 19 | Success(14), 20 | NotEnoughInStockMsg2(15), 21 | NotEnoughMesosMsg2(16), 22 | NeedMoreItemsMsg(19), 23 | NotEnoughStarCoinsMsg(20), 24 | MustBeUnderLevelMsgInt(21), 25 | MustBeOverLevelMsgInt(22), 26 | ItemPurchaseDateExpiredMsg(23), 27 | ItemHasBeenOutstockedMsgInt(24), 28 | CanOnlyBeBoughtOneByOneMsg(25), 29 | CannotBeMovedMsg(26), 30 | ShopRestockedMsgInt(27), 31 | CanOnlyPurchaseXMoreMsgInt(28), 32 | InactiveIPThereforeNoTradeMsg1Int(30), 33 | DifferentIPSoNoTradeAfterXMinMsgInt(31), 34 | CannotBeUsedMsg(32), 35 | CannotBeDoneOnThisWorldMsgByte(33), 36 | ItemDetailsChangedMsg(34), 37 | Below15LimitMsg(35), 38 | ; 39 | 40 | private int val; 41 | 42 | ShopResultType(int val) { 43 | this.val = val; 44 | } 45 | 46 | public int getVal() { 47 | return val; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/SpecStat.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | 6 | public enum SpecStat { 7 | runOnPickup, 8 | consumeOnPickup, 9 | hp, 10 | mp, 11 | hpR, 12 | mpR, 13 | eva, 14 | time, 15 | speed, 16 | mad, 17 | pad, 18 | acc, 19 | pdd, 20 | mdd, 21 | jump, 22 | imhp, 23 | immp, 24 | indieAllStat, 25 | indieSpeed, 26 | indieJump, 27 | indieSTR, 28 | indieDEX, 29 | indieINT, 30 | indieLUK, 31 | indiePad, 32 | indiePdd, 33 | indieMad, 34 | indieMdd, 35 | indieBDR, 36 | indieDamR, 37 | indieIgnoreMobpdpR, 38 | indieStatR, 39 | indieMhp, 40 | indieMmp, 41 | indieBooster, 42 | indieScriptBuff, 43 | incEffectHPPotion, 44 | indieAcc, 45 | indieEva, 46 | indieAllSkill, 47 | indieMhpR, 48 | indieMmpR, 49 | indieStance, 50 | indieForceSpeed, 51 | indieForceJump, 52 | indieQrPointTerm, 53 | indieWaterSmashBuff, 54 | padRate, 55 | madRate, 56 | pddRate, 57 | mddRate, 58 | accRate, 59 | evaRate, 60 | speedRate, 61 | mhpR, 62 | mhpRRate, 63 | mmpR, 64 | mmpRRate, 65 | booster, 66 | expinc, 67 | str, 68 | dex, 69 | inte, 70 | luk, 71 | asrR, 72 | bdR, 73 | prob, 74 | party, 75 | charismaEXP, 76 | insightEXP, 77 | willEXP, 78 | craftEXP, 79 | senseEXP, 80 | charmEXP, 81 | inflation, 82 | morph, 83 | repeatEffect, 84 | recipe, 85 | reqSkillLevel; 86 | public static SpecStat getSpecStatByName(String name) { 87 | if("int".equalsIgnoreCase(name)) { 88 | return inte; 89 | } 90 | return Arrays.stream(values()).filter(ss -> 91 | ss.toString().equalsIgnoreCase(name.toLowerCase())). 92 | findFirst(). 93 | orElse(null); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/SpellTraceScrollType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum SpellTraceScrollType { 5 | Normal, 6 | Innocence, 7 | CleanSlate 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/TextEffectType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | 4 | public enum TextEffectType { 5 | KinesisIntro(0), 6 | BlackFadedBrush(1), 7 | BurningField(2), 8 | TextNoBackground(3), 9 | ; 10 | 11 | private byte val; 12 | 13 | TextEffectType(int val) { this.val = (byte) val;} 14 | 15 | public byte getVal() { return val;} 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/TrunkOpType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import java.util.Arrays; 4 | 5 | 6 | public enum TrunkOpType { 7 | TrunkReq_Load(0), 8 | TrunkReq_Save(1), 9 | TrunkReq_Close(2), 10 | TrunkReq_CheckSSN2(3), 11 | TrunkReq_GetItem(4), 12 | TrunkReq_PutItem(5), 13 | TrunkReq_SortItem(6), 14 | TrunkReq_Money(7), 15 | TrunkReq_CloseDialog(8), 16 | TrunkRes_GetSuccess(9), 17 | TrunkRes_GetUnknown(10), 18 | TrunkRes_GetNoMoney(11), 19 | TruncRes_GetHavingOnlyItem(12), 20 | TrunkRes_PutSuccess(13), 21 | TrunkRes_PutIncorrectRequest(14), 22 | TrunkRes_SortItem(15), 23 | TrunkRes_PutNoMoney(16), 24 | TrunkRes_PutNoSpace(17), 25 | TrunkRes_PutUnknown(18), 26 | TrunkRes_MoneySuccess(19), 27 | TrunkRes_MoneyUnknown(20), 28 | TrunkRes_TrunkCheckSSN2(21), 29 | TrunkRes_OpenTrunkDlg(22), 30 | TrunkRes_TradeBlocked(23), 31 | TrunkRes_TradeBlocked_NotActive_Account(24), 32 | TrunkRes_TradeBlocked_Snapshot(25), 33 | TrunkRes_BlockedBehavior(26), 34 | TrunkRes_GetItemExpired(27), 35 | TrunkRes_BlockFunction(28), 36 | ; 37 | 38 | private final int val; 39 | 40 | TrunkOpType(int val) { 41 | this.val = val; 42 | } 43 | 44 | public static TrunkOpType getByVal(byte val) { 45 | return Arrays.stream(values()).filter(tt -> tt.getVal() == val).findAny().orElse(null); 46 | } 47 | 48 | public int getVal() { 49 | return val; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/enums/WhisperType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.enums; 2 | 3 | import im.cave.ms.tools.Util; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.enums 9 | * @date 1/9 23:20 10 | */ 11 | public enum WhisperType { 12 | Req_Find_GuildMember(5), 13 | Req_Whisper(6), 14 | Res_Find_GuildMember(9), 15 | Res_Whisper(10), 16 | 17 | Req_Find_Friend(68), 18 | Res_Find_Friend(72), 19 | ; 20 | private final byte val; 21 | 22 | WhisperType(byte val) { 23 | this.val = val; 24 | } 25 | 26 | WhisperType(int val) { 27 | this.val = (byte) val; 28 | } 29 | 30 | public static WhisperType getByVal(byte val) { 31 | return Util.findWithPred(values(), whisperType -> whisperType.val == val); 32 | } 33 | 34 | public byte getVal() { 35 | return val; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/data/EffectData.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.data; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.provider.data 7 | * @date 11/22 0:06 8 | */ 9 | public class EffectData { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/data/ReactorData.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.data; 2 | 3 | /** 4 | * 用处不大 5 | * 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.provider.data 9 | * @date 11/22 0:07 10 | */ 11 | public class ReactorData { 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/info/AndroidInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.info; 2 | 3 | import im.cave.ms.tools.Util; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author fair 12 | * @version V1.0 13 | * @Package im.cave.ms.client.field.obj 14 | * @date 1/1 17:35 15 | */ 16 | @Setter 17 | @Getter 18 | public class AndroidInfo { 19 | private byte type; 20 | private byte gender; 21 | private boolean shopUsable; 22 | private int chatBalloon; 23 | private int nameTag; 24 | private int accessory; 25 | private int longcoat; 26 | private int shoes; 27 | private List skins = new ArrayList<>(); 28 | private List faces = new ArrayList<>(); 29 | private List hairs = new ArrayList<>(); 30 | 31 | public AndroidInfo(byte type) { 32 | this.type = type; 33 | } 34 | 35 | public void addSkin(int skin) { 36 | skins.add(skin); 37 | } 38 | 39 | public void addFace(int face) { 40 | faces.add(face); 41 | } 42 | 43 | public void addHair(int hair) { 44 | hairs.add(hair); 45 | } 46 | 47 | public short getRandomFace() { 48 | return Util.getRandomFromCollection(faces).shortValue(); 49 | } 50 | 51 | public short getRandomHair() { 52 | return Util.getRandomFromCollection(hairs).shortValue(); 53 | } 54 | 55 | public short getRandomSkins() { 56 | return Util.getRandomFromCollection(skins).shortValue(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/info/CashItemInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.info; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | /** 7 | * @author fair 8 | * @version V1.0 9 | * @Package im.cave.ms.client.cashshop 10 | * @date 12/30 20:57 11 | */ 12 | @Getter 13 | @Setter 14 | public class CashItemInfo { 15 | private int SN; 16 | private int itemId; 17 | private int count; 18 | private int price; 19 | private int bonus; 20 | private int period; 21 | private int priority; 22 | private int reqPop; 23 | private int reqLev; 24 | private int gender; 25 | private boolean onSale; 26 | private int clazz; 27 | private int pbCash; 28 | private int pbPoint; 29 | private int pbGift; 30 | private boolean refundable; 31 | private boolean webShop; 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/info/FamiliarInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.info; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author fair 7 | * @version V1.0 8 | * @Package im.cave.ms.client.character 9 | * @date 12/19 18:48 10 | */ 11 | @Data 12 | public class FamiliarInfo { 13 | private int familiarId; 14 | private int mobId; 15 | private int range; 16 | private int skillId; 17 | private int effectAfter; 18 | private boolean boos; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/info/ItemRewardInfo.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.info; 2 | 3 | 4 | import im.cave.ms.client.character.items.Item; 5 | import im.cave.ms.provider.data.ItemData; 6 | import im.cave.ms.tools.DateUtil; 7 | 8 | import static im.cave.ms.constants.ServerConstants.MAX_TIME; 9 | 10 | public class ItemRewardInfo { 11 | private int count; 12 | private int itemId; 13 | private double prob; 14 | private int period; 15 | private String effect = ""; 16 | 17 | public void setCount(int count) { 18 | this.count = count; 19 | } 20 | 21 | public int getCount() { 22 | return count; 23 | } 24 | 25 | public void setItemId(int itemId) { 26 | this.itemId = itemId; 27 | } 28 | 29 | public int getItemId() { 30 | return itemId; 31 | } 32 | 33 | public void setProb(double prob) { 34 | this.prob = prob; 35 | } 36 | 37 | public double getProb() { 38 | return prob; 39 | } 40 | 41 | public void setPeriod(int period) { 42 | this.period = period; 43 | } 44 | 45 | public int getPeriod() { 46 | return period; 47 | } 48 | 49 | public void setEffect(String effect) { 50 | this.effect = effect; 51 | } 52 | 53 | public String getEffect() { 54 | return effect; 55 | } 56 | 57 | public Item getItem() { 58 | Item item = ItemData.getItemCopy(getItemId(), false); 59 | item.setQuantity(getCount()); 60 | item.setExpireTime(getPeriod() == 0 ? MAX_TIME : DateUtil.getFileTime(System.currentTimeMillis(), getPeriod())); 61 | return item; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/info/SkillOption.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.info; 2 | 3 | import im.cave.ms.tools.Pair; 4 | import org.objectweb.asm.Handle; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author fair 11 | * @version V1.0 12 | * @Package im.cave.ms.provider.info 13 | * @date 2/24 16:30 14 | */ 15 | public class SkillOption { 16 | private int id; 17 | private int skillId; 18 | private int reqLevel; 19 | private List> tempOptions = new ArrayList<>(); 20 | 21 | public int getId() { 22 | return id; 23 | } 24 | 25 | public void setId(int id) { 26 | this.id = id; 27 | } 28 | 29 | public int getSkillId() { 30 | return skillId; 31 | } 32 | 33 | public void setSkillId(int skillId) { 34 | this.skillId = skillId; 35 | } 36 | 37 | public int getReqLevel() { 38 | return reqLevel; 39 | } 40 | 41 | public void setReqLevel(int reqLevel) { 42 | this.reqLevel = reqLevel; 43 | } 44 | 45 | public List> getTempOptions() { 46 | return tempOptions; 47 | } 48 | 49 | public void setTempOptions(List> tempOptions) { 50 | this.tempOptions = tempOptions; 51 | } 52 | 53 | public void addTempOption(Pair tempOption) { 54 | tempOptions.add(tempOption); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/wz/MapleCanvas.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.wz; 2 | 3 | import javax.imageio.ImageIO; 4 | import java.awt.image.BufferedImage; 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | public class MapleCanvas { 9 | 10 | private final File file; 11 | private int width; 12 | private int height; 13 | private BufferedImage image; 14 | 15 | public MapleCanvas(int width, int height, File fileIn) { 16 | this.width = width; 17 | this.height = height; 18 | this.file = fileIn; 19 | } 20 | 21 | public int getHeight() { 22 | return height; 23 | } 24 | 25 | public int getWidth() { 26 | return width; 27 | } 28 | 29 | public BufferedImage getImage() { 30 | loadImageIfNecessary(); 31 | return image; 32 | } 33 | 34 | private void loadImageIfNecessary() { 35 | if (image == null) { 36 | try { 37 | image = ImageIO.read(file); 38 | // replace the dimensions loaded from the wz by the REAL dimensions from the image - should be equal tho 39 | width = image.getWidth(); 40 | height = image.getHeight(); 41 | } catch (IOException e) { 42 | throw new RuntimeException(e); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/wz/MapleDataDirectoryEntry.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.wz; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author Matze 11 | */ 12 | public class MapleDataDirectoryEntry extends MapleDataEntry { 13 | 14 | private final List subdirs = new ArrayList<>(); 15 | private final List files = new ArrayList<>(); 16 | private final Map entries = new HashMap<>(); 17 | 18 | public MapleDataDirectoryEntry(String name, int size, int checksum, MapleDataEntity parent) { 19 | super(name, size, checksum, parent); 20 | } 21 | 22 | public MapleDataDirectoryEntry() { 23 | super(null, 0, 0, null); 24 | } 25 | 26 | public void addDirectory(MapleDataDirectoryEntry dir) { 27 | subdirs.add(dir); 28 | entries.put(dir.getName(), dir); 29 | } 30 | 31 | public void addFile(MapleDataFileEntry fileEntry) { 32 | files.add(fileEntry); 33 | entries.put(fileEntry.getName(), fileEntry); 34 | } 35 | 36 | public List getSubdirectories() { 37 | return Collections.unmodifiableList(subdirs); 38 | } 39 | 40 | public List getFiles() { 41 | return Collections.unmodifiableList(files); 42 | } 43 | 44 | public MapleDataEntry getEntry(String name) { 45 | return entries.get(name); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/wz/MapleDataEntity.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.wz; 2 | 3 | public interface MapleDataEntity { 4 | 5 | String getName(); 6 | 7 | MapleDataEntity getParent(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/wz/MapleDataEntry.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.wz; 2 | 3 | /** 4 | * @author Matze 5 | */ 6 | public class MapleDataEntry implements MapleDataEntity { 7 | 8 | private final String name; 9 | private final int size; 10 | private final int checksum; 11 | private final MapleDataEntity parent; 12 | private int offset; 13 | 14 | public MapleDataEntry(String name, int size, int checksum, MapleDataEntity parent) { 15 | super(); 16 | this.name = name; 17 | this.size = size; 18 | this.checksum = checksum; 19 | this.parent = parent; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public int getSize() { 28 | return size; 29 | } 30 | 31 | public int getChecksum() { 32 | return checksum; 33 | } 34 | 35 | public int getOffset() { 36 | return offset; 37 | } 38 | 39 | @Override 40 | public MapleDataEntity getParent() { 41 | return parent; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/wz/MapleDataFileEntry.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.wz; 2 | 3 | public class MapleDataFileEntry extends MapleDataEntry { 4 | 5 | private int offset; 6 | 7 | public MapleDataFileEntry(String name, int size, int checksum, MapleDataEntity parent) { 8 | super(name, size, checksum, parent); 9 | } 10 | 11 | @Override 12 | public int getOffset() { 13 | return offset; 14 | } 15 | 16 | public void setOffset(int offset) { 17 | this.offset = offset; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/wz/MapleDataProviderFactory.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.wz; 2 | 3 | import java.io.File; 4 | 5 | public class MapleDataProviderFactory { 6 | 7 | private final static String wzPath = System.getProperty("wzpath"); 8 | 9 | private static MapleDataProvider getWZ(Object in) { 10 | if (in instanceof File) { 11 | return new MapleDataProvider((File) in); 12 | } 13 | throw new IllegalArgumentException("Can't create data provider for input " + in); 14 | } 15 | 16 | public static MapleDataProvider getDataProvider(Object in) { 17 | return getWZ(in); 18 | } 19 | 20 | public static File fileInWZPath(String filename) { 21 | return new File(wzPath, filename); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/provider/wz/MapleDataType.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.provider.wz; 2 | 3 | public enum MapleDataType { 4 | NONE, 5 | IMG_0x00, 6 | SHORT, 7 | INT, 8 | LONG, 9 | FLOAT, 10 | DOUBLE, 11 | STRING, 12 | EXTENDED, 13 | PROPERTY, 14 | CANVAS, 15 | VECTOR, 16 | CONVEX, 17 | SOUND, 18 | UOL, 19 | UNKNOWN_TYPE, 20 | UNKNOWN_EXTENDED_TYPE 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/scripting/ScriptException.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.scripting; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.scripting 7 | * @date 1/11 9:33 8 | */ 9 | public class ScriptException extends Exception { 10 | public ScriptException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/scripting/map/MapScriptManager.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.scripting.map; 2 | 3 | import im.cave.ms.client.MapleClient; 4 | import im.cave.ms.scripting.AbstractScriptManager; 5 | 6 | import javax.script.Invocable; 7 | import javax.script.ScriptException; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author fair 13 | * @version V1.0 14 | * @Package im.cave.ms.scripting.map 15 | * @date 11/27 21:54 16 | */ 17 | public class MapScriptManager extends AbstractScriptManager { 18 | private static final MapScriptManager instance = new MapScriptManager(); 19 | private final Map scripts = new HashMap<>(); 20 | 21 | 22 | public static MapScriptManager getInstance() { 23 | return instance; 24 | } 25 | 26 | private MapScriptManager() { 27 | super(); 28 | } 29 | 30 | 31 | public void reloadScripts() { 32 | scripts.clear(); 33 | } 34 | 35 | public boolean runMapScript(MapleClient c, String mapScriptPath) { 36 | Invocable iv = scripts.get(mapScriptPath); 37 | 38 | if (iv != null) { 39 | try { 40 | iv.invokeFunction("start", new MapScriptMethods(c)); 41 | return true; 42 | } catch (ScriptException | NoSuchMethodException e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | 47 | try { 48 | iv = getInvocable("map/" + mapScriptPath + ".js", c); 49 | if (iv == null) { 50 | return false; 51 | } 52 | scripts.put(mapScriptPath, iv); 53 | engine.put("ms", new MapScriptMethods(c)); 54 | iv.invokeFunction("start"); 55 | return true; 56 | } catch (ScriptException | NoSuchMethodException e) { 57 | log.error("{} 发生错误", mapScriptPath); 58 | e.printStackTrace(); 59 | } 60 | return false; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/scripting/map/MapScriptMethods.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.scripting.map; 2 | 3 | import im.cave.ms.client.MapleClient; 4 | import im.cave.ms.client.field.FieldEffect; 5 | import im.cave.ms.connection.packet.WorldPacket; 6 | import im.cave.ms.enums.FieldEffectType; 7 | import im.cave.ms.scripting.AbstractPlayerInteraction; 8 | 9 | /** 10 | * @author fair 11 | * @version V1.0 12 | * @Package im.cave.ms.scripting.map 13 | * @date 11/27 22:07 14 | */ 15 | public class MapScriptMethods extends AbstractPlayerInteraction { 16 | 17 | public MapScriptMethods(MapleClient c) { 18 | super(c); 19 | } 20 | 21 | public void setMobCapacity(int capacity) { 22 | c.getPlayer().getMap().setFixedMobCapacity(capacity); 23 | } 24 | 25 | public void generateMobs(boolean init) { 26 | c.getPlayer().getMap().generateMobs(init); 27 | } 28 | 29 | public void showEffect(String effectPath, int delay) { 30 | FieldEffect effect = new FieldEffect(); 31 | effect.setFieldEffectType(FieldEffectType.BackScreen); 32 | effect.setString(effectPath); 33 | effect.setArg1(delay); 34 | getChar().announce(WorldPacket.fieldEffect(effect)); 35 | } 36 | 37 | public void npcDisableInfo(int[] npcs) { 38 | getChar().announce(WorldPacket.npcDisableInfo(npcs)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/scripting/portal/PortalPlayerInteraction.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.scripting.portal; 2 | 3 | import im.cave.ms.client.MapleClient; 4 | import im.cave.ms.client.field.Portal; 5 | import im.cave.ms.scripting.AbstractPlayerInteraction; 6 | import im.cave.ms.scripting.map.MapScriptManager; 7 | 8 | /** 9 | * @author fair 10 | * @version V1.0 11 | * @Package im.cave.ms.scripting.portal 12 | * @date 11/28 14:16 13 | */ 14 | 15 | public class PortalPlayerInteraction extends AbstractPlayerInteraction { 16 | 17 | private final Portal portal; 18 | 19 | public PortalPlayerInteraction(MapleClient c, Portal portal) { 20 | super(c); 21 | this.portal = portal; 22 | } 23 | 24 | public void runMapScript() { 25 | MapScriptManager msm = MapScriptManager.getInstance(); 26 | msm.runMapScript(c, "onUserEnter/" + portal.getScript()); 27 | } 28 | 29 | public String getPortalName() { 30 | return portal.getName(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/scripting/quest/QuestActionManager.java: -------------------------------------------------------------------------------- 1 | 2 | package im.cave.ms.scripting.quest; 3 | 4 | import im.cave.ms.client.MapleClient; 5 | import im.cave.ms.scripting.npc.NpcConversationManager; 6 | 7 | /** 8 | * @author RMZero213 9 | */ 10 | public class QuestActionManager extends NpcConversationManager { 11 | private final boolean start; // this is if the script in question is start or end 12 | private final int quest; 13 | private String script; 14 | 15 | public QuestActionManager(MapleClient c, int quest, int npc, boolean start, String script) { 16 | super(c, npc, null, script); 17 | this.quest = quest; 18 | this.start = start; 19 | this.script = script; 20 | } 21 | 22 | public int getQuest() { 23 | return quest; 24 | } 25 | 26 | public boolean isStart() { 27 | return start; 28 | } 29 | 30 | @Override 31 | public void dispose() { 32 | QuestScriptManager.getInstance().dispose(getClient()); 33 | } 34 | 35 | public boolean forceStartQuest() { 36 | return forceStartQuest(quest); 37 | } 38 | 39 | public boolean forceCompleteQuest() { 40 | return forceCompleteQuest(quest); 41 | } 42 | 43 | // For compatibility with some older scripts... 44 | public void startQuest() { 45 | forceStartQuest(); 46 | } 47 | 48 | // For compatibility with some older scripts... 49 | public void completeQuest() { 50 | forceCompleteQuest(); 51 | } 52 | 53 | @Override 54 | public String getScript() { 55 | return script; 56 | } 57 | 58 | public void setScript(String script) { 59 | this.script = script; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/tools/Randomizer.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.tools; 2 | 3 | import java.security.SecureRandom; 4 | import java.util.Random; 5 | 6 | public class Randomizer { 7 | 8 | private static final Random rand = new Random(); 9 | 10 | public static int nextInt() { 11 | return rand.nextInt(); 12 | } 13 | 14 | public static int nextInt(final int arg0) { 15 | return rand.nextInt(arg0); 16 | } 17 | 18 | public static void nextBytes(final byte[] bytes) { 19 | rand.nextBytes(bytes); 20 | } 21 | 22 | public static boolean nextBoolean() { 23 | return rand.nextBoolean(); 24 | } 25 | 26 | public static double nextDouble() { 27 | return rand.nextDouble(); 28 | } 29 | 30 | public static float nextFloat() { 31 | return rand.nextFloat(); 32 | } 33 | 34 | public static long nextLong() { 35 | return rand.nextLong(); 36 | } 37 | 38 | public static int rand(final int lbound, final int ubound) { 39 | return nextInt(ubound - lbound + 1) + lbound; 40 | } 41 | 42 | public static boolean isSuccess(int rate) { 43 | return rate > nextInt(100); 44 | } 45 | 46 | public static int secureRandomInt(int max) { 47 | SecureRandom secureRandom = new SecureRandom(); 48 | return secureRandom.nextInt(max); 49 | } 50 | 51 | public static int secureRandomInt() { 52 | return (int) new SecureRandom().nextLong(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/tools/Triple.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.tools; 2 | 3 | 4 | public class Triple { 5 | private L left; 6 | private M middle; 7 | private R right; 8 | 9 | public Triple() { 10 | } 11 | 12 | public Triple(L left, M middle, R right) { 13 | this.left = left; 14 | this.middle = middle; 15 | this.right = right; 16 | } 17 | 18 | public L getLeft() { 19 | return left; 20 | } 21 | 22 | public void setLeft(L left) { 23 | this.left = left; 24 | } 25 | 26 | public M getMiddle() { 27 | return middle; 28 | } 29 | 30 | public void setMiddle(M middle) { 31 | this.middle = middle; 32 | } 33 | 34 | public R getRight() { 35 | return right; 36 | } 37 | 38 | public void setRight(R right) { 39 | this.right = right; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/tools/Tuple.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.tools; 2 | 3 | import java.util.Objects; 4 | 5 | 6 | public class Tuple { 7 | private L left; 8 | private R right; 9 | 10 | public Tuple(L left, R right) { 11 | this.left = left; 12 | this.right = right; 13 | } 14 | 15 | public L getLeft() { 16 | return left; 17 | } 18 | 19 | public void setLeft(L left) { 20 | this.left = left; 21 | } 22 | 23 | public R getRight() { 24 | return right; 25 | } 26 | 27 | public void setRight(R right) { 28 | this.right = right; 29 | } 30 | 31 | @Override 32 | public boolean equals(Object o) { 33 | if (this == o) return true; 34 | if (o == null || getClass() != o.getClass()) return false; 35 | Tuple tuple = (Tuple) o; 36 | return Objects.equals(left, tuple.left) && 37 | Objects.equals(right, tuple.right); 38 | } 39 | 40 | @Override 41 | public int hashCode() { 42 | return Objects.hash(left, right); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/tools/exception/CrackException.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.tools.exception; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.connection.handler.login 7 | * @date 11/21 15:21 8 | */ 9 | public class CrackException extends Exception { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/im/cave/ms/tools/exception/SkillException.java: -------------------------------------------------------------------------------- 1 | package im.cave.ms.tools.exception; 2 | 3 | /** 4 | * @author fair 5 | * @version V1.0 6 | * @Package im.cave.ms.tools.exception 7 | * @date 1/27 11:52 8 | */ 9 | public class SkillException extends Exception { 10 | public SkillException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/hibernate.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | org.hibernate.dialect.MySQLDialect 8 | 9 | 10 | 11 | com.mysql.cj.jdbc.Driver 12 | 13 | 14 | 15 | jdbc:mysql://localhost:3306/maple?autoReconnect=true&useSSL=false&serverTimezone=UTC 16 | 17 | 18 | 19 | root 20 | 21 | 22 | 23 | org.hibernate.hikaricp.internal.HikariCPConnectionProvider 24 | 25 | 26 | 27 | 123456 28 | 29 | 30 | 31 | true 32 | 33 | 34 | 35 | false 36 | 37 | 38 | 39 | true 40 | 41 | 42 | 43 | true 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/resources/rebel-remote.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | im.cave.ms 4 | 5 | --------------------------------------------------------------------------------