├── .github └── workflows │ └── gitlab-sync.yml ├── .gitignore ├── README.md └── gameserver ├── .idea ├── .gitignore ├── .name ├── artifacts │ └── java_server_jar.xml ├── compiler.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jarRepositories.xml ├── misc.xml ├── modules.xml ├── modules │ ├── com.shnok.javaserver.l2-server.main.iml │ ├── com.shnok.javaserver.l2-unity-gameserver.main.iml │ ├── l2-server.main.iml │ └── l2-unity-gameserver.main.iml ├── uiDesigner.xml └── vcs.xml ├── build.gradle ├── conf ├── character.properties ├── hexid.txt ├── log4j2.properties ├── npc.properties ├── rates.properties └── server.properties ├── db ├── l2-unity.mv.db ├── l2-unity.trace.db └── scripts │ ├── create-db.sql │ ├── create-dummy-players.sql │ ├── l2-unity │ ├── armor.sql │ ├── char_creation.sql │ ├── char_templates.sql │ ├── character.sql │ ├── create-npc-table.sql │ ├── create-spawnlist-table.sql │ ├── etcitem.sql │ ├── item.sql │ ├── lvlupgain.sql │ ├── npc-ue-to-unity-movespeed.sql │ ├── npc-ue-to-unity.sql │ ├── npc.sql │ ├── select-npc-classes.sql │ ├── spawnlist-17_25.sql │ ├── spawnlist-ue-to-unity.sql │ ├── spawnlist.sql │ └── weapon.sql │ ├── l2j │ ├── l2j_armor.sql │ ├── l2j_char_templates.sql │ ├── l2j_etcitem.sql │ └── l2j_weapon.sql │ └── populate-db.sql ├── geodata ├── 16_24.geodata ├── 16_25.geodata ├── 17_24.geodata └── 17_25.geodata ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── settings.gradle ├── src └── main │ └── java │ ├── META-INF │ └── MANIFEST.MF │ └── com │ └── shnok │ └── javaserver │ ├── Main.java │ ├── config │ ├── CharacterConfig.java │ ├── Configuration.java │ ├── Converter │ │ └── HexIdConverter.java │ ├── HexIdConfig.java │ ├── NpcConfig.java │ ├── RatesConfig.java │ └── ServerConfig.java │ ├── db │ ├── DbFactory.java │ ├── entity │ │ ├── DBArmor.java │ │ ├── DBCharTemplate.java │ │ ├── DBCharacter.java │ │ ├── DBEtcItem.java │ │ ├── DBItem.java │ │ ├── DBLevelUpGain.java │ │ ├── DBNpc.java │ │ ├── DBPlayerItem.java │ │ ├── DBSpawnList.java │ │ ├── DBWeapon.java │ │ └── DBZoneList.java │ ├── interfaces │ │ ├── ArmorDao.java │ │ ├── CharTemplateDao.java │ │ ├── CharacterDao.java │ │ ├── ClassLevelDao.java │ │ ├── EtcItemDao.java │ │ ├── NpcDao.java │ │ ├── PlayerItemDao.java │ │ ├── SpawnListDao.java │ │ ├── WeaponDao.java │ │ └── ZoneListDao.java │ └── repository │ │ ├── ArmorRepository.java │ │ ├── CharTemplateRepository.java │ │ ├── CharacterRepository.java │ │ ├── EtcItemRepository.java │ │ ├── LvlUpGainRepository.java │ │ ├── NpcRepository.java │ │ ├── PlayerItemRepository.java │ │ ├── SpawnListRepository.java │ │ ├── WeaponRepository.java │ │ └── ZoneListRepository.java │ ├── dto │ ├── Packet.java │ ├── ReceivablePacket.java │ ├── SendablePacket.java │ ├── external │ │ ├── ClientPacket.java │ │ ├── clientpackets │ │ │ ├── RequestActionUsePacket.java │ │ │ ├── RequestAttackPacket.java │ │ │ ├── RequestAutoAttackPacket.java │ │ │ ├── RequestCharacterAnimationPacket.java │ │ │ ├── RequestCharacterMoveDirection.java │ │ │ ├── RequestCharacterMovePacket.java │ │ │ ├── RequestCharacterRotatePacket.java │ │ │ ├── RequestSendMessagePacket.java │ │ │ ├── RequestSetTargetPacket.java │ │ │ ├── authentication │ │ │ │ ├── AuthLoginPacket.java │ │ │ │ ├── DisconnectPacket.java │ │ │ │ ├── ProtocolVersionPacket.java │ │ │ │ ├── RequestCharSelectPacket.java │ │ │ │ ├── RequestLoadWorldPacket.java │ │ │ │ └── RequestRestartPacket.java │ │ │ ├── item │ │ │ │ ├── RequestDestroyItemPacket.java │ │ │ │ ├── RequestDropItemPacket.java │ │ │ │ ├── RequestInventoryOpenPacket.java │ │ │ │ ├── RequestInventoryUpdateOrderPacket.java │ │ │ │ ├── RequestUnEquipItemPacket.java │ │ │ │ └── UseItemPacket.java │ │ │ └── shortcut │ │ │ │ ├── RequestShortcutDelPacket.java │ │ │ │ └── RequestShortcutRegPacket.java │ │ └── serverpackets │ │ │ ├── ActionAllowedPacket.java │ │ │ ├── ActionFailedPacket.java │ │ │ ├── ApplyDamagePacket.java │ │ │ ├── AutoAttackStartPacket.java │ │ │ ├── AutoAttackStopPacket.java │ │ │ ├── ChangeMoveTypePacket.java │ │ │ ├── ChangeWaitTypePacket.java │ │ │ ├── EntitySetTargetPacket.java │ │ │ ├── MessagePacket.java │ │ │ ├── NpcInfoPacket.java │ │ │ ├── ObjectAnimationPacket.java │ │ │ ├── ObjectDirectionPacket.java │ │ │ ├── ObjectMoveToPacket.java │ │ │ ├── ObjectPositionPacket.java │ │ │ ├── ObjectRotationPacket.java │ │ │ ├── PlayerInfoPacket.java │ │ │ ├── RemoveObjectPacket.java │ │ │ ├── ServerClosePacket.java │ │ │ ├── SocialActionPacket.java │ │ │ ├── StatusUpdatePacket.java │ │ │ ├── SystemMessagePacket.java │ │ │ ├── UserInfoPacket.java │ │ │ ├── authentication │ │ │ ├── CharSelectionInfoPacket.java │ │ │ ├── GameTimePacket.java │ │ │ ├── KeyPacket.java │ │ │ ├── LeaveWorldPacket.java │ │ │ ├── LoginFailPacket.java │ │ │ ├── PingPacket.java │ │ │ └── RestartResponsePacket.java │ │ │ ├── item │ │ │ ├── AbstractItemPacket.java │ │ │ ├── InventoryItemListPacket.java │ │ │ └── InventoryUpdatePacket.java │ │ │ └── shortcut │ │ │ ├── ShortcutInitPacket.java │ │ │ └── ShortcutRegisterPacket.java │ └── internal │ │ ├── LoginServerPacket.java │ │ ├── gameserver │ │ ├── AuthRequestPacket.java │ │ ├── BlowFishKeyPacket.java │ │ ├── PlayerAuthRequestPacket.java │ │ ├── PlayerInGamePacket.java │ │ ├── PlayerLogoutPacket.java │ │ ├── ReplyCharactersPacket.java │ │ └── ServerStatusPacket.java │ │ └── loginserver │ │ ├── AuthResponsePacket.java │ │ ├── InitLSPacket.java │ │ ├── KickPlayerPacket.java │ │ ├── LoginServerFailPacket.java │ │ ├── PlayerAuthResponsePacket.java │ │ └── RequestCharactersPacket.java │ ├── enums │ ├── ClassId.java │ ├── EntityAnimation.java │ ├── EntityMovingReason.java │ ├── Event.java │ ├── Intention.java │ ├── ItemLocation.java │ ├── LoginServerFailReason.java │ ├── MoveType.java │ ├── NpcType.java │ ├── PlayerAction.java │ ├── PlayerCondOverride.java │ ├── Race.java │ ├── ShortcutType.java │ ├── item │ │ ├── ArmorType.java │ │ ├── ConsumeType.java │ │ ├── EtcItemType.java │ │ ├── Grade.java │ │ ├── ItemCategory.java │ │ ├── ItemSlot.java │ │ ├── Material.java │ │ └── WeaponType.java │ └── network │ │ ├── GameClientState.java │ │ ├── LoginFailReason.java │ │ ├── SystemMessageId.java │ │ └── packettypes │ │ ├── external │ │ ├── ClientPacketType.java │ │ └── ServerPacketType.java │ │ └── internal │ │ ├── GameServerPacketType.java │ │ └── LoginServerPacketType.java │ ├── model │ ├── CharSelectInfoPackage.java │ ├── Hit.java │ ├── Party.java │ ├── PlayerAppearance.java │ ├── Point3D.java │ ├── WorldRegion.java │ ├── conditions │ │ ├── Condition.java │ │ └── ConditionListener.java │ ├── item │ │ ├── Inventory.java │ │ ├── ItemContainer.java │ │ ├── ItemInfo.java │ │ ├── PlayerInventory.java │ │ └── listeners │ │ │ ├── GearListener.java │ │ │ └── StatsListener.java │ ├── knownlist │ │ ├── EntityKnownList.java │ │ ├── NpcKnownList.java │ │ ├── ObjectKnownList.java │ │ └── PlayerKnownList.java │ ├── network │ │ ├── SessionKey.java │ │ └── WaitingClient.java │ ├── object │ │ ├── GameObject.java │ │ ├── ItemInstance.java │ │ ├── MovableObject.java │ │ └── entity │ │ │ ├── Entity.java │ │ │ ├── NpcInstance.java │ │ │ └── PlayerInstance.java │ ├── position │ │ └── ObjectPosition.java │ ├── shortcut │ │ ├── PlayerShortcuts.java │ │ └── Shortcut.java │ ├── skills │ │ ├── FormulasLegacy.java │ │ └── Skill.java │ ├── stats │ │ ├── Calculator.java │ │ ├── CharStat.java │ │ ├── Formulas.java │ │ ├── PlayerStat.java │ │ ├── Stats.java │ │ └── functions │ │ │ ├── AbstractFunction.java │ │ │ ├── Condition.java │ │ │ ├── fomulas │ │ │ ├── FuncMAtkAccuracy.java │ │ │ ├── FuncMAtkCritical.java │ │ │ ├── FuncMAtkEvasion.java │ │ │ ├── FuncMAtkMod.java │ │ │ ├── FuncMAtkSpeed.java │ │ │ ├── FuncMDefMod.java │ │ │ ├── FuncMaxCpMul.java │ │ │ ├── FuncMaxHpMul.java │ │ │ ├── FuncMaxMpMul.java │ │ │ ├── FuncMoveSpeed.java │ │ │ ├── FuncPAtkAccuracy.java │ │ │ ├── FuncPAtkCritical.java │ │ │ ├── FuncPAtkEvasion.java │ │ │ ├── FuncPAtkMod.java │ │ │ ├── FuncPAtkSpeed.java │ │ │ └── FuncPDefMod.java │ │ │ └── items │ │ │ ├── FuncItemStatAdd.java │ │ │ ├── FuncItemStatSet.java │ │ │ └── ItemStatConverter.java │ ├── status │ │ ├── NpcStatus.java │ │ ├── PlayerStatus.java │ │ └── Status.java │ └── template │ │ ├── EntityTemplate.java │ │ ├── NpcTemplate.java │ │ └── PlayerTemplate.java │ ├── pathfinding │ ├── Geodata.java │ ├── GeodataLoader.java │ ├── MoveData.java │ ├── PathFinding.java │ └── node │ │ ├── FastNodeList.java │ │ └── Node.java │ ├── security │ ├── BlowFishKeygen.java │ ├── BlowfishEngine.java │ ├── GameCrypt.java │ ├── LoginCrypt.java │ ├── NewCrypt.java │ ├── Rnd.java │ └── ScrambledKeyPair.java │ ├── service │ ├── AttackStanceManagerService.java │ ├── GameServerController.java │ ├── GameServerListenerService.java │ ├── GameTimeControllerService.java │ ├── ServerShutdownService.java │ ├── SpawnManagerService.java │ ├── ThreadPoolManagerService.java │ ├── WorldManagerService.java │ ├── db │ │ └── ItemTable.java │ └── factory │ │ ├── BitSetIDFactory.java │ │ ├── IdFactoryService.java │ │ └── PlayerFactoryService.java │ ├── thread │ ├── ClientPacketHandlerThread.java │ ├── GameClientThread.java │ ├── LoginServerPacketHandler.java │ ├── LoginServerThread.java │ ├── SpawnThread.java │ ├── ai │ │ ├── BaseAI.java │ │ ├── EntityAI.java │ │ ├── NpcAI.java │ │ ├── PlayerAI.java │ │ └── TestAI.java │ └── entity │ │ ├── ScheduleDestroyTask.java │ │ ├── ScheduleHitTask.java │ │ └── ScheduleNotifyAITask.java │ └── util │ ├── ByteUtils.java │ ├── HexUtils.java │ ├── PrimeFinder.java │ ├── ServerNameDAO.java │ ├── TimeUtils.java │ └── VectorUtils.java └── target └── .gitignore /.github/workflows/gitlab-sync.yml: -------------------------------------------------------------------------------- 1 | name: GitlabSync 2 | 3 | on: 4 | - push 5 | - delete 6 | 7 | jobs: 8 | sync: 9 | runs-on: ubuntu-latest 10 | name: Git Repo Sync 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | fetch-depth: 0 15 | - uses: wangchucheng/git-repo-sync@v0.1.0 16 | with: 17 | # Such as https://github.com/wangchucheng/git-repo-sync.git 18 | target-url: ${{ secrets.TARGET_URL }} 19 | # Such as wangchucheng 20 | target-username: ${{ secrets.TARGET_USERNAME }} 21 | # You can store token in your project's 'Setting > Secrets' and reference the name here. Such as ${{ secrets.ACCESS\_TOKEN }} 22 | target-token: ${{ secrets.TARGET_TOKEN }} 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### 2 | # VS/MD solution and project files 3 | ### 4 | unity-client/[Ee]xportedObj/ 5 | *.booproj 6 | *.csproj 7 | *.sln 8 | *.suo 9 | *.svd 10 | *.unityproj 11 | *.user 12 | *.userprefs 13 | *.pidb 14 | .DS_Store 15 | 16 | ### 17 | # OS generated 18 | ### 19 | .DS_Store 20 | .DS_Store? 21 | ._* 22 | .Spotlight-V100 23 | .Trashes 24 | Icon? 25 | ehthumbs.db 26 | Thumbs.db 27 | 28 | *.iws 29 | workspace.xml 30 | tasks.xml 31 | java-server/out/ 32 | *.bak 33 | *.log 34 | .gradle 35 | build -------------------------------------------------------------------------------- /gameserver/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /gameserver/.idea/.name: -------------------------------------------------------------------------------- 1 | l2-unity-gameserver -------------------------------------------------------------------------------- /gameserver/.idea/artifacts/java_server_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/artifacts/java_server_jar 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /gameserver/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /gameserver/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | -------------------------------------------------------------------------------- /gameserver/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /gameserver/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /gameserver/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gameserver/.idea/modules/com.shnok.javaserver.l2-server.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /gameserver/.idea/modules/com.shnok.javaserver.l2-unity-gameserver.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /gameserver/.idea/modules/l2-server.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /gameserver/.idea/modules/l2-unity-gameserver.main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /gameserver/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /gameserver/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'application' 4 | } 5 | 6 | group 'com.shnok.javaserver' 7 | version '0.0.6' 8 | 9 | repositories { 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | implementation fileTree(dir: 'libs', include: ['*.jar']) 15 | implementation 'org.apache.logging.log4j:log4j-api:2.21.0' 16 | implementation 'org.apache.logging.log4j:log4j-core:2.21.0' 17 | implementation 'org.apache.commons:commons-lang3:3.14.0' 18 | implementation 'javolution:javolution:5.5.1' 19 | implementation 'com.zaxxer:HikariCP:3.4.5' 20 | implementation 'org.hibernate:hibernate-core:5.4.32.Final' 21 | implementation 'org.hibernate:hibernate-hikaricp:5.4.32.Final' 22 | implementation 'com.h2database:h2:1.4.200' 23 | implementation 'org.slf4j:slf4j-api:1.7.36' 24 | implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.11.0' 25 | implementation 'org.aeonbits.owner:owner-java8:1.0.12' 26 | compileOnly 'org.projectlombok:lombok:1.18.30' 27 | annotationProcessor 'org.projectlombok:lombok:1.18.30' 28 | } 29 | 30 | application { 31 | // Specify the main class for your application 32 | mainClassName = 'com.shnok.javaserver.Main' 33 | } 34 | 35 | 36 | mainClassName="com.shnok.javaserver.Main" 37 | jar { 38 | duplicatesStrategy = DuplicatesStrategy.EXCLUDE 39 | manifest { 40 | attributes 'Main-Class': 'com.shnok.javaserver.Main' 41 | } 42 | from { 43 | configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /gameserver/conf/hexid.txt: -------------------------------------------------------------------------------- 1 | #the hexID to auth into login 2 | #Thu Sep 05 00:40:28 SGT 2024 3 | HexID=81a8ba90db0e77d303397388e25ecefa 4 | ServerID=1 5 | -------------------------------------------------------------------------------- /gameserver/conf/npc.properties: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------- 2 | # NPC Settings 3 | # --------------------------------------------------------------------------- 4 | # This properties file is solely for NPC modifications and settings that directly influence them. 5 | # The defaults are set to be retail-like. 6 | # If you modify any of these settings, your server will deviate from being retail-like. 7 | # Warning: 8 | # Please take extreme caution when changing anything. 9 | # Also, please understand what you are changing before you do so on a live server. 10 | 11 | # --------------------------------------------------------------------------- 12 | # General 13 | # --------------------------------------------------------------------------- 14 | 15 | # The penalty in percent for -2 till -5 level differences 16 | # default: 17 | # normal - 0.7, 0.6, 0.6, 0.55 18 | # critical - 0.75, 0.65, 0.6, 0.58 19 | # skill - 0.8, 0.7, 0.65, 0.62 20 | lvl.difference.dmg.penalty = 0.7,0.6,0.6,0.55 21 | lvl.difference.crit.dmg.penalty = 0.75,0.65,0.6,0.58 22 | lvl.difference.skill.dmg.penalty = 0.8,0.7,0.65,0.62 23 | 24 | 25 | # The penalty in percent for -3 till -6 level differences 26 | # Default: 2.5,3.0,3.25,3.5 27 | lvl.difference.skill.chance.penalty = 2.5,3.0,3.25,3.5 -------------------------------------------------------------------------------- /gameserver/conf/rates.properties: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------- 2 | # Rate Settings 3 | # --------------------------------------------------------------------------- 4 | # The defaults are set to be retail-like. If you modify any of these settings your server will deviate from being retail-like. 5 | # Warning: 6 | # Please take extreme caution when changing anything. Also please understand what you are changing before you do so on a live server. 7 | 8 | # --------------------------------------------------------------------------- 9 | # Item Rates 10 | # --------------------------------------------------------------------------- 11 | 12 | # --------------------------------------------------------------------------- 13 | # Standard Settings 14 | # --------------------------------------------------------------------------- 15 | 16 | # Experience multiplier 17 | rate.xp = 1 18 | # Skill points multiplier 19 | rate.sp = 1 20 | # Experience multiplier (Party) 21 | rate.party.xp = 1 22 | # Skill points multiplier (Party) 23 | rate.party.sp = 1 24 | # Karma decreasing rate 25 | # Default: 1 26 | rate.karma.lost = 1 27 | rate.karma.exp.lost = 1 -------------------------------------------------------------------------------- /gameserver/db/l2-unity.mv.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shnok/l2-unity-gameserver/d5d10e3cefc09f1d28bb32b8dcc94f70db9b45d4/gameserver/db/l2-unity.mv.db -------------------------------------------------------------------------------- /gameserver/db/scripts/create-dummy-players.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO "CHARACTER" (ACCOUNT_NAME,CHAR_NAME,TITLE,RACE,CLASS_ID,ACCESS_LEVEL,ONLINE,CHAR_SLOT,"LEVEL",HP,MAX_HP,CP,MAX_CP,MP,MAX_MP,ACC,CRITICAL,EVASION,M_ATK,M_DEF,M_SPD,P_ATK,P_DEF,P_SPD,RUN_SPD,WALK_SPD,STR,CON,DEX,"_INT",MEN,WIT,FACE,HAIR_STYLE,HAIR_COLOR,SEX,HEADING,X,Y,Z,COLR,COLH,"EXP",SP,KARMA,PVP_KILLS,PK_KILLS,CLAN_ID,MAX_WEIGHT,ONLINE_TIME,LAST_LOGIN,DELETE_TIME) VALUES 2 | ('03b08430','03b08430','',2,38,0,false,0,1,122,122,61,61,47,47,29,41,29,6,41,333,3,54,300,122,1,23,24,23,44,37,19,1,0,0,1,0.0,4724.32,-68.0,-1731.24,0.13,0.45,0,0,0,0,0,NULL,0,0,0,NULL), 3 | ('c37a464a','c37a464a','',2,31,0,false,0,1,108,108,43,43,35,35,35,45,35,6,41,333,4,80,300,122,1,41,32,34,25,26,12,0,1,1,1,0.0,4724.32,-68.0,-1731.24,0.13,0.45,0,0,0,0,0,NULL,0,0,0,NULL), 4 | ('b531a060','b531a060','',4,53,0,false,0,1,93,93,65,65,35,35,33,43,33,6,41,333,4,80,300,115,1,39,45,29,20,27,10,0,1,1,1,0.0,4724.32,-68.0,-1731.24,0.1,0.36,0,0,0,0,0,NULL,0,0,0,NULL), 5 | ('cc172828','cc172828','',4,53,0,false,0,1,93,93,65,65,35,35,33,43,33,6,41,333,4,80,300,115,1,39,45,29,20,27,10,0,0,0,1,0.0,4724.32,-68.0,-1731.24,0.1,0.36,0,0,0,0,0,NULL,0,0,0,NULL), 6 | ('bfdd0de3','bfdd0de3','',4,53,0,false,0,1,93,93,65,65,35,35,33,43,33,6,41,333,4,80,300,115,1,39,45,29,20,27,10,0,0,0,1,0.0,4724.32,-68.0,-1731.24,0.1,0.36,0,0,0,0,0,NULL,0,0,0,NULL), 7 | ('c3bd4a79','c3bd4a79','',2,31,0,false,0,1,108,108,43,43,35,35,35,45,35,6,41,333,4,80,300,122,1,41,32,34,25,26,12,0,0,0,1,0.0,4724.32,-68.0,-1731.24,0.13,0.45,0,0,0,0,0,NULL,0,0,0,NULL); 8 | 9 | 10 | INSERT INTO PLAYER_ITEM (OWNER_ID,ITEM_ID,COUNT,ENCHANT_LEVEL,LOC,SLOT,PRICE_SELL,PRICE_BUY) VALUES 11 | (1,425,1,0,1,1,0,0), 12 | (1,461,1,0,1,2,0,0), 13 | (1,6,1,0,1,6,0,0), 14 | (2,1147,1,0,1,1,0,0), 15 | (2,1146,1,0,1,2,0,0), 16 | (2,2370,1,0,1,6,0,0), 17 | (3,1147,1,0,1,1,0,0), 18 | (3,1146,1,0,1,2,0,0), 19 | (3,89,1,0,1,6,0,0), 20 | (4,1147,1,0,1,1,0,0); 21 | INSERT INTO PLAYER_ITEM (OWNER_ID,ITEM_ID,COUNT,ENCHANT_LEVEL,LOC,SLOT,PRICE_SELL,PRICE_BUY) VALUES 22 | (4,1146,1,0,1,2,0,0), 23 | (4,5284,1,0,1,6,0,0), 24 | (5,1147,1,0,1,1,0,0), 25 | (5,1146,1,0,1,2,0,0), 26 | (5,177,1,0,1,5,0,0), 27 | (6,177,1,0,1,6,0,0), 28 | (1,20,1,0,1,5,0,0); 29 | -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/armor.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS `ARMOR`; 2 | CREATE TABLE `ARMOR` ( 3 | `item_id` int(11) NOT NULL default '0', 4 | `name` varchar(70) default NULL, 5 | `bodypart` varchar(15) NOT NULL default '', 6 | `crystallizable` varchar(5) NOT NULL default '', 7 | `armor_type` varchar(5) NOT NULL default '', 8 | `weight` int(5) NOT NULL default '0', 9 | `material` varchar(15) NOT NULL default '', 10 | `crystal_type` varchar(4) NOT NULL default '', 11 | `avoid_modify` int(1) NOT NULL default '0', 12 | `duration` int(3) NOT NULL default '0', 13 | `p_def` int(3) NOT NULL default '0', 14 | `m_def` int(2) NOT NULL default '0', 15 | `mp_bonus` int(3) NOT NULL default '0', 16 | `price` int(11) NOT NULL default '0', 17 | `crystal_count` int(4) default NULL, 18 | `sellable` varchar(5) default NULL, 19 | `dropable` varchar(5) default NULL, 20 | `destroyable` varchar(5) default NULL, 21 | `tradeable` varchar(5) default NULL, 22 | PRIMARY KEY (`item_id`) 23 | ); 24 | 25 | -- 26 | -- Dumping data for table `armor` 27 | 28 | INSERT INTO `ARMOR` VALUES 29 | ('425','Apprentice''s Tunic','chest','false','magic','2150','cloth','none','0','-1','17','0','19','26','0','false','false','true','false'), 30 | ('461','Apprentice''s Stockings','legs','false','magic','1100','cloth','none','0','-1','10','0','10','6','0','false','false','true','false'), 31 | ('1146','Squire''s Shirt','chest','false','light','3301','cloth','none','0','-1','33','0','0','26','0','false','false','true','false'), 32 | ('1147','Squire''s Pants','legs','false','light','1750','cloth','none','0','-1','20','0','0','6','0','false','false','true','false'); -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/char_templates.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Table structure for table `L2J_CHAR_TEMPLATES` 3 | -- 4 | 5 | DROP TABLE IF EXISTS `CHAR_TEMPLATE`; 6 | CREATE TABLE `CHAR_TEMPLATE` ( 7 | `ClassId` int(11) NOT NULL default '0', 8 | `ClassName` varchar(20) NOT NULL default '', 9 | `RaceId` int(1) NOT NULL default '0', 10 | `STR` int(2) NOT NULL default '0', 11 | `CON` int(2) NOT NULL default '0', 12 | `DEX` int(2) NOT NULL default '0', 13 | `_INT` int(2) NOT NULL default '0', 14 | `WIT` int(2) NOT NULL default '0', 15 | `MEN` int(2) NOT NULL default '0', 16 | `P_ATK` int(3) NOT NULL default '0', 17 | `P_DEF` int(3) NOT NULL default '0', 18 | `M_ATK` int(3) NOT NULL default '0', 19 | `M_DEF` int(2) NOT NULL default '0', 20 | `P_SPD` int(3) NOT NULL default '0', 21 | `M_SPD` int(3) NOT NULL default '0', 22 | `ACC` int(3) NOT NULL default '0', 23 | `CRITICAL` int(3) NOT NULL default '0', 24 | `EVASION` int(3) NOT NULL default '0', 25 | `MOVE_SPD` int(3) NOT NULL default '0', 26 | `x` decimal(10,2) NOT NULL default '0', 27 | `y` decimal(10,2) NOT NULL default '0', 28 | `z` decimal(10,2) NOT NULL default '0', 29 | `items1` int(4) NOT NULL default '0', 30 | `items2` int(4) NOT NULL default '0', 31 | `items3` int(4) NOT NULL default '0', 32 | `items4` int(4) NOT NULL default '0', 33 | `items5` int(10) NOT NULL default '0', 34 | `F_COL_H` decimal(10,2) NOT NULL default '0', 35 | `F_COL_R` decimal(10,2) NOT NULL default '0', 36 | `M_COL_H` decimal(10,2) NOT NULL default '0', 37 | `M_COL_R` decimal(10,2) NOT NULL default '0', 38 | PRIMARY KEY (`ClassId`) 39 | ); 40 | 41 | INSERT INTO CHAR_TEMPLATES 42 | (ClassId, ClassName, RaceId, STR, CON, DEX, _INT, WIT, MEN, P_ATK, P_DEF, M_ATK, M_DEF, P_SPD, M_SPD, ACC, CRITICAL, EVASION, MOVE_SPD, x, y, z, items1, items2, items3, items4, items5, F_COL_H, F_COL_R, M_COL_H, M_COL_R) 43 | SELECT ClassId, ClassName, RaceId, STR, CON, DEX, _INT, WIT, MEN, P_ATK, P_DEF, M_ATK, M_DEF, P_SPD, M_SPD, ACC, CRITICAL, EVASION, MOVE_SPD, (y / (52.5)), (z / (52.5)), (x / (52.5)), items1, items2, items3, items4, items5, (F_COL_H/52.5), (F_COL_R/52.5), (M_COL_H/52.5), (M_COL_R/52.5) FROM L2J_CHAR_TEMPLATES; 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/character.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS CHARACTER; 2 | CREATE TABLE IF NOT EXISTS CHARACTER ( 3 | id INT AUTO_INCREMENT PRIMARY KEY, 4 | account_name VARCHAR(64) NOT NULL, 5 | char_name VARCHAR(64) NOT NULL, 6 | title VARCHAR(64) DEFAULT '', 7 | race TINYINT DEFAULT 0, 8 | class_id TINYINT DEFAULT 0, 9 | access_level INT DEFAULT 0, 10 | online BOOLEAN DEFAULT FALSE, 11 | char_slot TINYINT DEFAULT 0, 12 | level INT DEFAULT 1, 13 | hp INT DEFAULT 1, 14 | max_hp INT DEFAULT 1, 15 | cp INT DEFAULT 1, 16 | max_cp INT DEFAULT 1, 17 | mp INT DEFAULT 1, 18 | max_mp INT DEFAULT 1, 19 | acc INT DEFAULT 1, 20 | critical INT DEFAULT 1, 21 | evasion INT DEFAULT 1, 22 | m_atk INT DEFAULT 1, 23 | m_def INT DEFAULT 1, 24 | m_spd INT DEFAULT 1, 25 | p_atk INT DEFAULT 1, 26 | p_def INT DEFAULT 1, 27 | p_spd INT DEFAULT 1, 28 | run_spd INT DEFAULT 1, 29 | walk_spd INT DEFAULT 1, 30 | str TINYINT DEFAULT 1, 31 | con TINYINT DEFAULT 1, 32 | dex TINYINT DEFAULT 1, 33 | _int TINYINT DEFAULT 1, 34 | men TINYINT DEFAULT 1, 35 | wit TINYINT DEFAULT 1, 36 | face TINYINT DEFAULT 0, 37 | hair_style TINYINT DEFAULT 0, 38 | hair_color TINYINT DEFAULT 0, 39 | sex TINYINT DEFAULT 0, 40 | heading FLOAT DEFAULT 0, 41 | x FLOAT DEFAULT 0, 42 | y FLOAT DEFAULT 0, 43 | z FLOAT DEFAULT 0, 44 | colR FLOAT DEFAULT 0, 45 | colH FLOAT DEFAULT 0, 46 | exp BIGINT DEFAULT 0, 47 | sp BIGINT DEFAULT 0, 48 | karma INT DEFAULT 0, 49 | pvp_kills INT DEFAULT 0, 50 | pk_kills INT DEFAULT 0, 51 | clan_id INT, 52 | max_weight INT DEFAULT 0, 53 | online_time BIGINT DEFAULT 0, 54 | last_login BIGINT DEFAULT 0, 55 | delete_time BIGINT 56 | ); -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/create-npc-table.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS `npc`; 2 | CREATE TABLE `npc`( 3 | `id` decimal(11,0) NOT NULL default '0', 4 | `idTemplate` int(11) NOT NULL default '0', 5 | `name` varchar(200) default NULL, 6 | `serverSideName` int(1) default '0', 7 | `title` varchar(45) default '', 8 | `serverSideTitle` int(1) default '0', 9 | `class` varchar(200) default NULL, 10 | `collision_radius` decimal(5,2) default NULL, 11 | `collision_height` decimal(5,2) default NULL, 12 | `level` decimal(2,0) default NULL, 13 | `sex` varchar(6) default NULL, 14 | `type` varchar(20) default NULL, 15 | `attackrange` int(11) default NULL, 16 | `hp` decimal(8,0) default NULL, 17 | `mp` decimal(5,0) default NULL, 18 | `hpreg` decimal(8,2) default NULL, 19 | `mpreg` decimal(5,2) default NULL, 20 | `str` decimal(7,0) default NULL, 21 | `con` decimal(7,0) default NULL, 22 | `dex` decimal(7,0) default NULL, 23 | `int` decimal(7,0) default NULL, 24 | `wit` decimal(7,0) default NULL, 25 | `men` decimal(7,0) default NULL, 26 | `exp` decimal(9,0) default NULL, 27 | `sp` decimal(8,0) default NULL, 28 | `patk` decimal(5,0) default NULL, 29 | `pdef` decimal(5,0) default NULL, 30 | `matk` decimal(5,0) default NULL, 31 | `mdef` decimal(5,0) default NULL, 32 | `atkspd` decimal(3,0) default NULL, 33 | `aggro` decimal(6,0) default NULL, 34 | `matkspd` decimal(4,0) default NULL, 35 | `rhand` decimal(4,0) default NULL, 36 | `lhand` decimal(4,0) default NULL, 37 | `armor` decimal(1,0) default NULL, 38 | `walkspd` decimal(3,0) default NULL, 39 | `runspd` decimal(3,0) default NULL, 40 | `faction_id` varchar(40) default NULL, 41 | `faction_range` decimal(4,0) default NULL, 42 | `isUndead` int(11) default 0, 43 | `absorb_level` decimal(2,0) default 0, 44 | `absorb_type` enum('FULL_PARTY','LAST_HIT','PARTY_ONE_RANDOM') DEFAULT 'LAST_HIT' NOT NULL, 45 | PRIMARY KEY (`id`) 46 | ) -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/create-spawnlist-table.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `spawnlist` ( 2 | `id` int(11) NOT NULL auto_increment, 3 | `location` varchar(40) NOT NULL default '', 4 | `count` int(9) NOT NULL default '0', 5 | `npc_templateid` int(9) NOT NULL default '0', 6 | `locx` int(9) NOT NULL default '0', 7 | `locy` int(9) NOT NULL default '0', 8 | `locz` int(9) NOT NULL default '0', 9 | `randomx` int(9) NOT NULL default '0', 10 | `randomy` int(9) NOT NULL default '0', 11 | `heading` int(9) NOT NULL default '0', 12 | `respawn_delay` int(9) NOT NULL default '0', 13 | `loc_id` int(9) NOT NULL default '0', 14 | `periodOfDay` decimal(2,0) default '0') -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/etcitem.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Table structure for table `etcitem` 3 | -- 4 | 5 | DROP TABLE IF EXISTS `etcitem`; 6 | CREATE TABLE `etcitem` ( 7 | `item_id` decimal(11,0) NOT NULL DEFAULT '0', 8 | `name` varchar(100) DEFAULT NULL, 9 | `crystallizable` varchar(5) DEFAULT NULL, 10 | `item_type` varchar(12) DEFAULT NULL, 11 | `weight` decimal(4,0) DEFAULT NULL, 12 | `consume_type` varchar(9) DEFAULT NULL, 13 | `material` varchar(11) DEFAULT NULL, 14 | `crystal_type` varchar(4) DEFAULT NULL, 15 | `duration` decimal(3,0) DEFAULT NULL, 16 | `price` decimal(11,0) DEFAULT NULL, 17 | `crystal_count` int(4) DEFAULT NULL, 18 | `sellable` varchar(5) DEFAULT NULL, 19 | `dropable` varchar(5) DEFAULT NULL, 20 | `destroyable` varchar(5) DEFAULT NULL, 21 | `tradeable` varchar(5) DEFAULT NULL, 22 | `id_name` varchar(100) NOT NULL DEFAULT '', 23 | `drop_category` enum('0','1','2') NOT NULL DEFAULT '2', 24 | PRIMARY KEY (`item_id`) 25 | ); 26 | 27 | -- ---------------------------- 28 | -- Records of etcitem 29 | -- ---------------------------- 30 | INSERT INTO `etcitem` VALUES ('17', 'Wooden Arrow', 'false', 'arrow', '6', 'stackable', 'wood', 'none', '-1', '2', '0', 'true', 'true', 'true', 'true', 'wooden_arrow', '2'); 31 | INSERT INTO `etcitem` VALUES ('57', 'Adena', 'false', 'none', '0', 'asset', 'gold', 'none', '-1', '1', '0', 'true', 'true', 'true', 'true', 'adena', '2'); 32 | INSERT INTO `etcitem` VALUES ('65', 'Red Potion', 'false', 'potion', '80', 'stackable', 'liquid', 'none', '-1', '40', '0', 'true', 'true', 'true', 'true', 'red_potion', '2'); 33 | INSERT INTO `etcitem` VALUES ('1835', 'Soulshot: No Grade', 'false', 'shot', '4', 'stackable', 'paper', 'none', '-1', '7', '0', 'true', 'true', 'true', 'true', 'soulshot_none', '2'); 34 | INSERT INTO `etcitem` VALUES ('2509', 'Spiritshot: No Grade', 'false', 'shot', '5', 'stackable', 'paper', 'none', '-1', '15', '0', 'true', 'true', 'true', 'true', 'spiritshot_none', '2'); 35 | INSERT INTO `etcitem` VALUES ('3947', 'Blessed Spiritshot: No Grade', 'false', 'shot', '5', 'stackable', 'paper', 'none', '-1', '35', '0', 'true', 'true', 'true', 'true', 'blessed_spiritshot_none', '2'); -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/item.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS ITEM; 2 | CREATE TABLE IF NOT EXISTS ITEM ( 3 | object_id INT AUTO_INCREMENT PRIMARY KEY, 4 | owner_id INT NOT NULL, 5 | item_id INT NOT NULL, 6 | count INT DEFAULT 1, 7 | enchant_level TINYINT DEFAULT 0, 8 | loc TINYINT NOT NULL, 9 | slot INT DEFAULT 0, 10 | price_sell INT DEFAULT 0, 11 | price_buy INT DEFAULT 0, 12 | CONSTRAINT fk_owner_id FOREIGN KEY (owner_id) REFERENCES CHARACTER(id) ON DELETE CASCADE 13 | ); -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/npc-ue-to-unity-movespeed.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE PUBLIC.NPC MODIFY COLUMN WALKSPD DECIMAL(10,2); 2 | ALTER TABLE PUBLIC.NPC MODIFY COLUMN RUNSPD DECIMAL(10,2); 3 | 4 | UPDATE PUBLIC.NPC 5 | SET 6 | WALKSPD=WALKSPD/52.5, 7 | RUNSPD=RUNSPD/52.5; -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/npc-ue-to-unity.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE PUBLIC.NPC MODIFY COLUMN ATTACKRANGE DECIMAL(10,2); 2 | ALTER TABLE PUBLIC.NPC MODIFY COLUMN COLLISION_RADIUS DECIMAL(10,2); 3 | ALTER TABLE PUBLIC.NPC MODIFY COLUMN COLLISION_HEIGHT DECIMAL(10,2); 4 | ALTER TABLE PUBLIC.NPC MODIFY COLUMN AGGRO_RANGE DECIMAL(10,2); 5 | ALTER TABLE PUBLIC.NPC MODIFY COLUMN FACTION_RANGE DECIMAL(10,2); 6 | 7 | UPDATE PUBLIC.NPC 8 | SET 9 | ATTACKRANGE=ATTACKRANGE/52.5, 10 | COLLISION_RADIUS=COLLISION_RADIUS/52.5, 11 | COLLISION_HEIGHT=COLLISION_HEIGHT/52.5, 12 | ATTACKRANGE=ATTACKRANGE/52.5, 13 | AGGRO_RANGE=AGGRO_RANGE/52.5, 14 | FACTION_RANGE=FACTION_RANGE/52.5; -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/select-npc-classes.sql: -------------------------------------------------------------------------------- 1 | -- SELECT NPCS THAT WERE NOT ADDED 2 | SELECT DISTINCT n.CLASS 3 | FROM L2J_SPAWNLIST ljs 4 | INNER JOIN NPC n ON n.IDTEMPLATE = ljs.NPC_TEMPLATEID 5 | WHERE 6 | (ljs.LOCATION LIKE '%1624%' OR 7 | ljs.LOCATION LIKE '%1724%' OR 8 | ljs.LOCATION LIKE '%1625%') 9 | AND n.CLASS NOT IN ( 10 | SELECT DISTINCT n_inner.CLASS 11 | FROM L2J_SPAWNLIST ljs_inner 12 | INNER JOIN NPC n_inner ON n_inner.IDTEMPLATE = ljs_inner.NPC_TEMPLATEID 13 | WHERE 14 | ljs_inner.LOCATION LIKE '%1725%' 15 | ); 16 | 17 | 18 | -- SELECT ALL NPCS FOR GIVEN MAPS 19 | SELECT DISTINCT n.CLASS 20 | FROM L2J_SPAWNLIST ljs 21 | INNER JOIN NPC n ON n.IDTEMPLATE = ljs.NPC_TEMPLATEID 22 | WHERE 23 | (ljs.LOCATION LIKE '%1624%' OR 24 | ljs.LOCATION LIKE '%1724%' OR 25 | ljs.LOCATION LIKE '%1625%' OR 26 | ljs.LOCATION LIKE '%1725%'); -------------------------------------------------------------------------------- /gameserver/db/scripts/l2-unity/spawnlist-ue-to-unity.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE PUBLIC.SPAWNLIST MODIFY COLUMN LOCX DECIMAL(10,2); 2 | ALTER TABLE PUBLIC.SPAWNLIST MODIFY COLUMN LOCY DECIMAL(10,2); 3 | ALTER TABLE PUBLIC.SPAWNLIST MODIFY COLUMN LOCZ DECIMAL(10,2); 4 | ALTER TABLE PUBLIC.SPAWNLIST MODIFY COLUMN RANDOMX DECIMAL(10,2); 5 | ALTER TABLE PUBLIC.SPAWNLIST MODIFY COLUMN RANDOMY DECIMAL(10,2); 6 | ALTER TABLE PUBLIC.SPAWNLIST MODIFY COLUMN HEADING DECIMAL(10,2); 7 | 8 | UPDATE PUBLIC.SPAWNLIST 9 | SET 10 | LOCX=LOCY/52.5, 11 | LOCY=LOCZ/52.5, 12 | LOCZ=LOCX/52.5, 13 | RANDOMX=RANDOMY/52.5, 14 | RANDOMY=RANDOMX/52.5, 15 | HEADING=HEADING/182.04, 16 | RESPAWN_DELAY=RESPAWN_DELAY*1000.0; 17 | -------------------------------------------------------------------------------- /gameserver/geodata/16_24.geodata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shnok/l2-unity-gameserver/d5d10e3cefc09f1d28bb32b8dcc94f70db9b45d4/gameserver/geodata/16_24.geodata -------------------------------------------------------------------------------- /gameserver/geodata/16_25.geodata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shnok/l2-unity-gameserver/d5d10e3cefc09f1d28bb32b8dcc94f70db9b45d4/gameserver/geodata/16_25.geodata -------------------------------------------------------------------------------- /gameserver/geodata/17_24.geodata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shnok/l2-unity-gameserver/d5d10e3cefc09f1d28bb32b8dcc94f70db9b45d4/gameserver/geodata/17_24.geodata -------------------------------------------------------------------------------- /gameserver/geodata/17_25.geodata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shnok/l2-unity-gameserver/d5d10e3cefc09f1d28bb32b8dcc94f70db9b45d4/gameserver/geodata/17_25.geodata -------------------------------------------------------------------------------- /gameserver/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shnok/l2-unity-gameserver/d5d10e3cefc09f1d28bb32b8dcc94f70db9b45d4/gameserver/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gameserver/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gameserver/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'l2-unity-gameserver' 2 | 3 | -------------------------------------------------------------------------------- /gameserver/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.shnok.javaserver.service.GameServerController 3 | Class-Path: commons-lang3-3.12.0.jar javolution-5.5.1.jar 4 | 5 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/Main.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver; 2 | 3 | import com.shnok.javaserver.pathfinding.Geodata; 4 | import com.shnok.javaserver.pathfinding.PathFinding; 5 | import com.shnok.javaserver.service.*; 6 | import com.shnok.javaserver.service.db.ItemTable; 7 | import com.shnok.javaserver.service.factory.IdFactoryService; 8 | import com.shnok.javaserver.thread.LoginServerThread; 9 | import lombok.extern.log4j.Log4j2; 10 | import org.apache.logging.log4j.core.config.Configurator; 11 | 12 | @Log4j2 13 | public class Main { 14 | public static void main(String[] args) { 15 | runServer(args); 16 | } 17 | 18 | public static void runServer(String... args) { 19 | log.info("Starting application."); 20 | Configurator.initialize(null, "conf/log4j2.properties"); 21 | 22 | ThreadPoolManagerService.getInstance().initialize(); 23 | Runtime.getRuntime().addShutdownHook(ServerShutdownService.getInstance()); 24 | IdFactoryService.getInstance(); 25 | 26 | ItemTable.getInstance(); 27 | 28 | Geodata.getInstance().loadGeodata(); 29 | PathFinding.getInstance(); 30 | 31 | WorldManagerService.getInstance().initialize(); 32 | GameTimeControllerService.getInstance().initialize(); 33 | SpawnManagerService.getInstance().initialize(); 34 | AttackStanceManagerService.getInstance(); 35 | GameServerListenerService.getInstance().Initialize(); 36 | GameServerListenerService.getInstance().start(); 37 | LoginServerThread.getInstance().start(); 38 | 39 | try { 40 | LoginServerThread.getInstance().join(); 41 | GameServerListenerService.getInstance().join(); 42 | } catch (InterruptedException e) { 43 | e.printStackTrace(); 44 | } 45 | log.info("Application closed"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/config/Configuration.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.config; 2 | 3 | import lombok.Getter; 4 | import org.aeonbits.owner.ConfigCache; 5 | 6 | import java.net.URISyntaxException; 7 | import java.net.URL; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | 11 | import static org.apache.logging.log4j.core.util.Loader.getClassLoader; 12 | 13 | @Getter 14 | public class Configuration { 15 | public static final String DEFAULT_PATH = "conf/"; 16 | 17 | public static final HexIdConfig hexId = ConfigCache.getOrCreate(HexIdConfig.class); 18 | public static final ServerConfig server = ConfigCache.getOrCreate(ServerConfig.class); 19 | public static final CharacterConfig character = ConfigCache.getOrCreate(CharacterConfig.class); 20 | public static final NpcConfig npc = ConfigCache.getOrCreate(NpcConfig.class); 21 | public static final RatesConfig rates = ConfigCache.getOrCreate(RatesConfig.class); 22 | 23 | public static String getDefaultPath(String filename) { 24 | return DEFAULT_PATH + filename; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/config/Converter/HexIdConverter.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.config.Converter; 2 | 3 | import java.lang.reflect.Method; 4 | import java.math.BigInteger; 5 | 6 | import org.aeonbits.owner.Converter; 7 | import org.apache.logging.log4j.util.Strings; 8 | 9 | /** 10 | * Hex Id Converter. 11 | * @author Zoey76 12 | * @version 2.6.1.0 13 | */ 14 | public class HexIdConverter implements Converter { 15 | 16 | @Override 17 | public BigInteger convert(Method method, String input) { 18 | if (Strings.isBlank(input)) { 19 | return null; 20 | } 21 | 22 | return new BigInteger(input, 16); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/config/HexIdConfig.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.config; 2 | 3 | import com.shnok.javaserver.config.Converter.HexIdConverter; 4 | import org.aeonbits.owner.Accessible; 5 | import org.aeonbits.owner.Config; 6 | import org.aeonbits.owner.Config.HotReload; 7 | import org.aeonbits.owner.Config.Sources; 8 | import org.aeonbits.owner.Mutable; 9 | import org.aeonbits.owner.Reloadable; 10 | 11 | import java.math.BigInteger; 12 | 13 | import static java.util.concurrent.TimeUnit.MINUTES; 14 | import static org.aeonbits.owner.Config.HotReloadType.ASYNC; 15 | import static org.aeonbits.owner.Config.LoadType.MERGE; 16 | 17 | @Sources({ 18 | "file:./conf/" + HexIdConfig.FILENAME, 19 | "classpath:conf/" + HexIdConfig.FILENAME 20 | }) 21 | @Config.LoadPolicy(MERGE) 22 | @HotReload(value = 20, unit = MINUTES, type = ASYNC) 23 | public interface HexIdConfig extends Mutable, Reloadable, Accessible { 24 | String FILENAME = "hexid.txt"; 25 | 26 | String SERVERID_KEY = "ServerID"; 27 | String HEXID_KEY = "HexID"; 28 | 29 | @Key(SERVERID_KEY) 30 | Integer getServerID(); 31 | 32 | @Key(HEXID_KEY) 33 | @ConverterClass(HexIdConverter.class) 34 | BigInteger getHexID(); 35 | } 36 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/config/NpcConfig.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.config; 2 | 3 | import org.aeonbits.owner.Config; 4 | import org.aeonbits.owner.Mutable; 5 | import org.aeonbits.owner.Reloadable; 6 | 7 | import static java.util.concurrent.TimeUnit.MINUTES; 8 | import static org.aeonbits.owner.Config.HotReloadType.ASYNC; 9 | import static org.aeonbits.owner.Config.LoadType.MERGE; 10 | 11 | @Config.Sources({ 12 | "file:./conf/npc.properties", 13 | "classpath:conf/npc.properties" 14 | }) 15 | @Config.LoadPolicy(MERGE) 16 | @Config.HotReload(value = 20, unit = MINUTES, type = ASYNC) 17 | public interface NpcConfig extends Mutable, Reloadable { 18 | 19 | @Config.Key("lvl.difference.dmg.penalty") 20 | @Config.Separator(",") 21 | Float[] lvlDifferenceDmgPenalty(); 22 | @Config.Key("lvl.difference.crit.dmg.penalty") 23 | @Config.Separator(",") 24 | Float[] lvlDifferenceCritDmgPenalty(); 25 | @Config.Key("lvl.difference.skill.dmg.penalty") 26 | @Config.Separator(",") 27 | Float[] lvlDifferenceSkillDmgPenalty(); 28 | @Config.Key("lvl.difference.skill.chance.penalty") 29 | @Config.Separator(",") 30 | Float[] lvlDifferenceSkillChancePenalty(); 31 | } 32 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/config/RatesConfig.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.config; 2 | 3 | import org.aeonbits.owner.Config; 4 | import org.aeonbits.owner.Mutable; 5 | import org.aeonbits.owner.Reloadable; 6 | 7 | import static java.util.concurrent.TimeUnit.MINUTES; 8 | import static org.aeonbits.owner.Config.HotReloadType.ASYNC; 9 | import static org.aeonbits.owner.Config.LoadType.MERGE; 10 | 11 | @Config.Sources({ 12 | "file:./conf/rates.properties", 13 | "classpath:conf/rates.properties" 14 | }) 15 | @Config.LoadPolicy(MERGE) 16 | @Config.HotReload(value = 20, unit = MINUTES, type = ASYNC) 17 | public interface RatesConfig extends Mutable, Reloadable { 18 | 19 | @Config.Key("rate.xp") 20 | Integer ratesXp(); 21 | @Config.Key("rate.sp") 22 | Integer ratesSp(); 23 | @Config.Key("rate.party.xp") 24 | Integer ratePartyXp(); 25 | @Config.Key("rate.party.sp") 26 | Integer ratePartySp(); 27 | @Config.Key("rate.karma.lost") 28 | Integer rateKarmaLost(); 29 | @Config.Key("rate.karma.exp.lost") 30 | Integer rateKarmaExpLost(); 31 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBArmor.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.enums.item.ArmorType; 4 | import com.shnok.javaserver.enums.item.ItemSlot; 5 | import lombok.*; 6 | 7 | import javax.persistence.*; 8 | 9 | @Getter 10 | @Setter 11 | @ToString(callSuper = true) 12 | @EqualsAndHashCode(callSuper = true) 13 | @Entity 14 | @Table(name = "ARMOR") 15 | public class DBArmor extends DBItem { 16 | @Id 17 | @Column(name = "ITEM_ID") 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private int id; 20 | @Column(name = "BODYPART") 21 | @Enumerated(EnumType.STRING) 22 | private ItemSlot bodyPart; 23 | @Column(name = "ARMOR_TYPE") 24 | @Enumerated(EnumType.STRING) 25 | private ArmorType type; 26 | @Column(name = "AVOID_MODIFY") 27 | private int avoidModify; 28 | @Column(name = "P_DEF") 29 | private int pDef; 30 | @Column(name = "M_DEF") 31 | private int mDef; 32 | @Column(name = "MP_BONUS") 33 | private int mpBonus; 34 | @Transient 35 | private boolean stackable = false; 36 | } 37 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBCharTemplate.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.enums.ClassId; 4 | import com.shnok.javaserver.enums.Race; 5 | import lombok.Data; 6 | 7 | import javax.persistence.*; 8 | 9 | @Entity 10 | @Table(name = "CHAR_TEMPLATE") 11 | @Data 12 | public class DBCharTemplate { 13 | @Column 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | private int classId; 17 | @Column 18 | private String className; 19 | @Column(name = "RaceId") 20 | private Race race; 21 | @Column(name = "STR") 22 | private int str; 23 | @Column(name = "CON") 24 | private int con; 25 | @Column(name = "DEX") 26 | private int dex; 27 | @Column(name = "_INT") 28 | private int _int; 29 | @Column(name = "WIT") 30 | private int wit; 31 | @Column(name = "MEN") 32 | private int men; 33 | @Column(name = "P_ATK") 34 | private int pAtk; 35 | @Column(name = "P_DEF") 36 | private int pDef; 37 | @Column(name = "M_ATK") 38 | private int mAtk; 39 | @Column(name = "M_DEF") 40 | private int mDef; 41 | @Column(name = "P_SPD") 42 | private int pAtkSpd; 43 | @Column(name = "M_SPD") 44 | private int mAtkSpd; 45 | @Column(name = "ACC") 46 | private int acc; 47 | @Column(name = "CRITICAL") 48 | private int critical; 49 | @Column(name = "EVASION") 50 | private int evasion; 51 | @Column(name = "MOVE_SPD") 52 | private int moveSpd; 53 | @Column(name = "X") 54 | private float posX; 55 | @Column(name = "Y") 56 | private int posY; 57 | @Column(name = "Z") 58 | private int posZ; 59 | @Column(name = "F_COL_H") 60 | private float collisionHeightFemale; 61 | @Column(name = "F_COL_R") 62 | private float collisionRadiusFemale; 63 | @Column(name = "M_COL_H") 64 | private float collisionHeightMale; 65 | @Column(name = "M_COL_R") 66 | private float collisionRadiusMale; 67 | 68 | private int items1; 69 | private int items2; 70 | private int items3; 71 | private int items4; 72 | private int items5; 73 | } 74 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBEtcItem.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.enums.item.ConsumeType; 4 | import com.shnok.javaserver.enums.item.EtcItemType; 5 | import com.shnok.javaserver.enums.item.ItemSlot; 6 | import lombok.*; 7 | 8 | import javax.persistence.*; 9 | 10 | @Getter 11 | @Setter 12 | @ToString(callSuper = true) 13 | @EqualsAndHashCode(callSuper = true) 14 | @Entity 15 | @Table(name = "ETCITEM") 16 | public class DBEtcItem extends DBItem { 17 | @Id 18 | @Column(name = "ITEM_ID") 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | protected int id; 21 | @Column(name = "CONSUME_TYPE") 22 | @Enumerated(EnumType.STRING) 23 | @Access(AccessType.PROPERTY) 24 | private ConsumeType consumeType; 25 | @Column(name = "ITEM_TYPE") 26 | @Enumerated(EnumType.STRING) 27 | private EtcItemType type; 28 | @Column(name = "ID_NAME") 29 | private String idName; 30 | @Column(name = "DROP_CATEGORY") 31 | private int dropCategory; 32 | @Transient 33 | private ItemSlot bodyPart; 34 | @Transient 35 | private boolean stackable; 36 | 37 | public void setConsumeType(ConsumeType type) { 38 | consumeType = type; 39 | stackable = type == ConsumeType.stackable; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBItem.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.enums.item.Grade; 4 | import com.shnok.javaserver.enums.item.ItemCategory; 5 | import com.shnok.javaserver.enums.item.ItemSlot; 6 | import com.shnok.javaserver.enums.item.Material; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import lombok.ToString; 10 | 11 | import javax.persistence.*; 12 | 13 | @Getter 14 | @Setter 15 | @ToString 16 | @MappedSuperclass 17 | public abstract class DBItem { 18 | @Id 19 | @Column(name = "ITEM_ID") 20 | @GeneratedValue(strategy = GenerationType.IDENTITY) 21 | protected int id; 22 | @Column(name = "NAME") 23 | protected String name; 24 | @Column(name = "WEIGHT") 25 | protected int weight; 26 | @Column(name = "MATERIAL") 27 | @Enumerated(EnumType.STRING) 28 | protected Material material; 29 | @Transient 30 | protected Enum type; 31 | @Transient 32 | protected ItemSlot bodyPart; 33 | @Column(name = "CRYSTAL_TYPE") 34 | @Enumerated(EnumType.STRING) 35 | protected Grade grade; 36 | @Column(name = "DURATION") 37 | protected int duration; 38 | @Column(name = "PRICE") 39 | protected int price; 40 | @Column(name = "CRYSTAL_COUNT") 41 | protected int crystalCount; 42 | @Column(name = "SELLABLE") 43 | protected boolean sellable; 44 | @Column(name = "DROPABLE") 45 | protected boolean droppable; 46 | @Column(name = "DESTROYABLE") 47 | protected boolean destroyable; 48 | @Column(name = "TRADEABLE") 49 | protected boolean tradeable; 50 | @Transient 51 | protected boolean stackable; 52 | } 53 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBLevelUpGain.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.*; 6 | 7 | @Data 8 | @Entity 9 | @Table(name = "LVLUPGAIN") 10 | public class DBLevelUpGain { 11 | @Id 12 | @Column(name = "CLASSID") 13 | @GeneratedValue(strategy = GenerationType.IDENTITY) 14 | protected int classId; 15 | 16 | @Column(name = "DEFAULTHPBASE") 17 | protected float defaultHpBase; 18 | @Column(name = "DEFAULTHPADD") 19 | protected float defaultHpAdd; 20 | @Column(name = "DEFAULTHPMOD") 21 | protected float defaultHpMod; 22 | 23 | @Column(name = "DEFAULTMPBASE") 24 | protected float defaultMpBase; 25 | @Column(name = "DEFAULTMPADD") 26 | protected float defaultMpAdd; 27 | @Column(name = "DEFAULTMPMOD") 28 | protected float defaultMpMod; 29 | 30 | @Column(name = "DEFAULTCPBASE") 31 | protected float defaultCpBase; 32 | @Column(name = "DEFAULTCPADD") 33 | protected float defaultCpAdd; 34 | @Column(name = "DEFAULTCPMOD") 35 | protected float defaultCpMod; 36 | 37 | @Column(name = "CLASS_LVL") 38 | protected int classLevel; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBNpc.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.enums.NpcType; 4 | import lombok.Data; 5 | 6 | import javax.persistence.*; 7 | 8 | @Entity 9 | @Data 10 | @Table(name = "NPC") 11 | public class DBNpc { 12 | @Id 13 | private int id; 14 | private int idTemplate; 15 | private String name; 16 | private int serverSideName; 17 | private String title; 18 | private int serverSideTitle; 19 | @Column(name = "class") 20 | private String npcClass; 21 | @Column(name = "collision_radius") 22 | private float collisionRadius; 23 | @Column(name = "collision_height") 24 | private float collisionHeight; 25 | private int level; 26 | private String sex; 27 | @Enumerated(EnumType.STRING) 28 | private NpcType type; 29 | @Column(name = "attackrange") 30 | private float attackRange; 31 | private int hp; 32 | private int mp; 33 | @Column(name = "hpreg") 34 | private float hpReg; 35 | @Column(name = "mpreg") 36 | private float mpReg; 37 | private byte str; 38 | private byte con; 39 | private byte dex; 40 | @Column(name = "int") 41 | private byte intStat; 42 | private byte wit; 43 | private byte men; 44 | private int exp; 45 | private int sp; 46 | private int patk; 47 | private int pdef; 48 | private int matk; 49 | private int mdef; 50 | private int atkspd; 51 | private float aggro; 52 | private int matkspd; 53 | private int rhand; 54 | private int lhand; 55 | private int armor; 56 | private int walkspd; 57 | private int runspd; 58 | @Column(name = "faction_id") 59 | private String factionId; 60 | @Column(name = "faction_range") 61 | private float factionRange; 62 | private int isUndead; 63 | @Column(name = "absorb_level") 64 | private int absorbLevel; 65 | 66 | @Enumerated(EnumType.STRING) 67 | @Column(name = "absorb_type") 68 | private AbsorbType absorbType; 69 | 70 | public enum AbsorbType { 71 | FULL_PARTY, 72 | LAST_HIT, 73 | PARTY_ONE_RANDOM 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBPlayerItem.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.enums.ItemLocation; 4 | import com.shnok.javaserver.enums.item.ItemSlot; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import javax.persistence.*; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Entity 15 | @Table(name = "PLAYER_ITEM") 16 | public class DBPlayerItem { 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | @Column(name = "object_id") 21 | private int objectId; 22 | 23 | @Column(name = "owner_id") 24 | private int ownerId; 25 | 26 | @Column(name = "item_id") 27 | private int itemId; 28 | 29 | @Column(name = "loc") 30 | private ItemLocation location; 31 | 32 | @Column(name = "slot") 33 | private int slot; 34 | 35 | @Column(name = "count") 36 | private int count; 37 | 38 | @Column(name = "enchant_level") 39 | private byte enchantLevel; 40 | 41 | @Column(name = "price_sell") 42 | private int priceSell; 43 | 44 | @Column(name = "price_buy") 45 | private int priceBuy; 46 | 47 | public DBPlayerItem(int ownerId, int itemId, ItemLocation location, ItemSlot slot) { 48 | this.ownerId = ownerId; 49 | this.itemId = itemId; 50 | this.location = location; 51 | this.slot = slot.getValue(); 52 | 53 | priceBuy = 0; 54 | priceSell = 0; 55 | count = 1; 56 | } 57 | 58 | public DBPlayerItem(int ownerId, int itemId, ItemLocation location, int slot, int count) { 59 | this.ownerId = ownerId; 60 | this.itemId = itemId; 61 | this.location = location; 62 | this.slot = slot; 63 | 64 | priceBuy = 0; 65 | priceSell = 0; 66 | this.count = count; 67 | } 68 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBWeapon.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.enums.item.ItemSlot; 4 | import com.shnok.javaserver.enums.item.WeaponType; 5 | import lombok.*; 6 | 7 | import javax.persistence.*; 8 | 9 | @Getter 10 | @Setter 11 | @ToString(callSuper = true) 12 | @EqualsAndHashCode(callSuper = true) 13 | @Entity 14 | @Table(name = "WEAPON") 15 | public class DBWeapon extends DBItem { 16 | @Id 17 | @Column(name = "ITEM_ID") 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | protected int id; 20 | @Column(name = "BODYPART") 21 | @Enumerated(EnumType.STRING) 22 | private ItemSlot bodyPart; 23 | @Column(name = "SOULSHOTS") 24 | private byte soulshots; 25 | @Column(name = "SPIRITSHOTS") 26 | private byte spiritshots; 27 | @Column(name = "P_DAM") 28 | private int pAtk; 29 | @Column(name = "M_DAM") 30 | private int mAtk; 31 | @Column(name = "RND_DAM") 32 | private int rndDmg; 33 | @Column(name = "WEAPONTYPE") 34 | @Enumerated(EnumType.STRING) 35 | private WeaponType type; 36 | @Column(name = "CRITICAL") 37 | private int critical; 38 | @Column(name = "HIT_MODIFY") 39 | private int hitModify; 40 | @Column(name = "AVOID_MODIFY") 41 | private int avoidModify; 42 | @Column(name = "SHIELD_DEF") 43 | private int shieldDef; 44 | @Column(name = "SHIELD_DEF_RATE") 45 | private int shieldDefRate; 46 | @Column(name = "ATK_SPEED") 47 | private int atkSpd; 48 | @Column(name = "MP_CONSUME") 49 | private int mpConsume; 50 | @Transient 51 | private boolean stackable = false; 52 | @Transient 53 | private float baseAttackRange = 0.733f; 54 | @Transient 55 | private int baseAttackAngle = 120; 56 | } 57 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/entity/DBZoneList.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.entity; 2 | 3 | import com.shnok.javaserver.model.Point3D; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.*; 9 | 10 | @Entity 11 | @Table(name = "ZONELIST") 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class DBZoneList { 16 | 17 | @Column 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private String id; 21 | @Column(name = "ORIG_X") 22 | private float origX; 23 | @Column(name = "ORIG_Y") 24 | private float origY; 25 | @Column(name = "ORIG_Z") 26 | private float origZ; 27 | @Column(name = "SIZE") 28 | private float zoneSize; 29 | 30 | public Point3D getOrigin() { 31 | return new Point3D(origX, origY, origZ); 32 | } 33 | 34 | public boolean isInBounds(Point3D location) { 35 | if(location.getX() < origX) { 36 | return false; 37 | } 38 | if(location.getX() > origX + zoneSize) { 39 | return false; 40 | } 41 | if(location.getZ() < origZ) { 42 | return false; 43 | } 44 | if(location.getZ() > origZ + zoneSize) { 45 | return false; 46 | } 47 | 48 | return true; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/ArmorDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBArmor; 4 | 5 | import java.util.List; 6 | 7 | public interface ArmorDao { 8 | public DBArmor getArmorById(int id); 9 | 10 | public List getAllArmors(); 11 | } 12 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/CharTemplateDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBCharTemplate; 4 | 5 | import java.util.List; 6 | 7 | public interface CharTemplateDao { 8 | List getAllCharTemplates(); 9 | 10 | public DBCharTemplate getTemplateByClassId(int id); 11 | } 12 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/CharacterDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBCharacter; 4 | 5 | import java.util.List; 6 | 7 | public interface CharacterDao { 8 | public DBCharacter getRandomCharacter(); 9 | public DBCharacter getCharacterById(int id); 10 | public List getCharactersForAccount(String account); 11 | 12 | List getAllCharacters(); 13 | 14 | public void saveOrUpdateCharacter(DBCharacter character); 15 | 16 | int saveCharacter(DBCharacter character); 17 | 18 | void setCharacterOnlineStatus(int id, boolean isOnline); 19 | } 20 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/ClassLevelDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBLevelUpGain; 4 | 5 | import java.util.List; 6 | 7 | public interface ClassLevelDao { 8 | public DBLevelUpGain getLevelUpGainByClassId(int id); 9 | 10 | List getAllLevelUpGainData(); 11 | } 12 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/EtcItemDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBEtcItem; 4 | 5 | import java.util.List; 6 | 7 | public interface EtcItemDao { 8 | public DBEtcItem getEtcItemById(int id); 9 | public List getAllEtcItems(); 10 | } 11 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/NpcDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBNpc; 4 | 5 | public interface NpcDao { 6 | public DBNpc getNpcById(int id); 7 | } 8 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/PlayerItemDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBPlayerItem; 4 | 5 | import java.util.List; 6 | 7 | public interface PlayerItemDao { 8 | List getAllPlayerItems(); 9 | 10 | List getAllItemsForUser(int id); 11 | List getEquippedItemsForUser(int id); 12 | List getInventoryItemsForUser(int id); 13 | List getWarehouseItemsForUser(int id); 14 | public int savePlayerItem(DBPlayerItem playerItem); 15 | } 16 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/SpawnListDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBSpawnList; 4 | 5 | import java.util.List; 6 | 7 | public interface SpawnListDao { 8 | public void addSpawnList(DBSpawnList spawnList); 9 | public DBSpawnList getSpawnListById(int id); 10 | public List getAllSpawnList(); 11 | 12 | List getAllMonsters(); 13 | 14 | List getAllNPCs(); 15 | } 16 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/WeaponDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBWeapon; 4 | 5 | import java.util.List; 6 | 7 | public interface WeaponDao { 8 | public DBWeapon getWeaponById(int id); 9 | public List getAllWeapons(); 10 | } 11 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/interfaces/ZoneListDao.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.interfaces; 2 | 3 | import com.shnok.javaserver.db.entity.DBZoneList; 4 | 5 | import java.util.List; 6 | 7 | public interface ZoneListDao { 8 | public List getAllZoneList(); 9 | public DBZoneList getZoneListById(String id); 10 | } 11 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/repository/ArmorRepository.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.repository; 2 | 3 | import com.shnok.javaserver.db.DbFactory; 4 | import com.shnok.javaserver.db.entity.DBArmor; 5 | import com.shnok.javaserver.db.interfaces.ArmorDao; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.hibernate.Session; 8 | 9 | import java.util.List; 10 | 11 | @Log4j2 12 | public class ArmorRepository implements ArmorDao { 13 | @Override 14 | public DBArmor getArmorById(int id) { 15 | try (Session session = DbFactory.getSessionFactory().openSession()) { 16 | return session.get(DBArmor.class, id); 17 | } catch (Exception e) { 18 | log.error("SQL ERROR: {}", e.getMessage(), e); 19 | return null; 20 | } 21 | } 22 | 23 | @Override 24 | public List getAllArmors() { 25 | try (Session session = DbFactory.getSessionFactory().openSession()) { 26 | return session.createQuery("SELECT a FROM DBArmor a", DBArmor.class) 27 | .getResultList(); 28 | } catch (Exception e) { 29 | log.error("SQL ERROR: {}", e.getMessage(), e); 30 | return null; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/repository/CharTemplateRepository.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.repository; 2 | 3 | import com.shnok.javaserver.db.DbFactory; 4 | import com.shnok.javaserver.db.entity.DBCharTemplate; 5 | import com.shnok.javaserver.db.interfaces.CharTemplateDao; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.hibernate.Session; 8 | 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | @Log4j2 14 | public class CharTemplateRepository implements CharTemplateDao { 15 | private final Map charTemplateLookup; 16 | private static CharTemplateRepository instance; 17 | public static CharTemplateRepository getInstance() { 18 | if (instance == null) { 19 | instance = new CharTemplateRepository(); 20 | } 21 | return instance; 22 | } 23 | 24 | public CharTemplateRepository() { 25 | charTemplateLookup = new HashMap<>(); 26 | 27 | List data = getAllCharTemplates(); 28 | 29 | data.forEach((d) -> { 30 | charTemplateLookup.put(d.getClassId(), d); 31 | }); 32 | } 33 | 34 | @Override 35 | public List getAllCharTemplates() { 36 | try (Session session = DbFactory.getSessionFactory().openSession()) { 37 | return session.createQuery("SELECT e FROM DBCharTemplate e", DBCharTemplate.class) 38 | .getResultList(); 39 | } catch (Exception e) { 40 | log.error("SQL ERROR: {}", e.getMessage(), e); 41 | return null; 42 | } 43 | } 44 | 45 | @Override 46 | public DBCharTemplate getTemplateByClassId(int id) { 47 | return charTemplateLookup.get(id); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/repository/EtcItemRepository.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.repository; 2 | 3 | import com.shnok.javaserver.db.DbFactory; 4 | import com.shnok.javaserver.db.entity.DBEtcItem; 5 | import com.shnok.javaserver.db.interfaces.EtcItemDao; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.hibernate.Session; 8 | 9 | import java.util.List; 10 | 11 | @Log4j2 12 | public class EtcItemRepository implements EtcItemDao { 13 | @Override 14 | public DBEtcItem getEtcItemById(int id) { 15 | try (Session session = DbFactory.getSessionFactory().openSession()) { 16 | return session.get(DBEtcItem.class, id); 17 | } catch (Exception e) { 18 | log.error("SQL ERROR: {}", e.getMessage(), e); 19 | return null; 20 | } 21 | } 22 | 23 | @Override 24 | public List getAllEtcItems() { 25 | try (Session session = DbFactory.getSessionFactory().openSession()) { 26 | return session.createQuery("SELECT e FROM DBEtcItem e", DBEtcItem.class) 27 | .getResultList(); 28 | } catch (Exception e) { 29 | log.error("SQL ERROR: {}", e.getMessage(), e); 30 | return null; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/repository/NpcRepository.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.repository; 2 | 3 | import com.shnok.javaserver.db.DbFactory; 4 | import com.shnok.javaserver.db.entity.DBNpc; 5 | import com.shnok.javaserver.db.interfaces.NpcDao; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.hibernate.Session; 8 | 9 | @Log4j2 10 | public class NpcRepository implements NpcDao { 11 | @Override 12 | public DBNpc getNpcById(int id) { 13 | try (Session session = DbFactory.getSessionFactory().openSession()) { 14 | return session.get(DBNpc.class, id); 15 | } catch (Exception e) { 16 | log.error("SQL ERROR: {}", e.getMessage(), e); 17 | return null; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/repository/WeaponRepository.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.repository; 2 | 3 | import com.shnok.javaserver.db.DbFactory; 4 | import com.shnok.javaserver.db.entity.DBWeapon; 5 | import com.shnok.javaserver.db.interfaces.WeaponDao; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.hibernate.Session; 8 | 9 | import java.util.List; 10 | 11 | @Log4j2 12 | public class WeaponRepository implements WeaponDao { 13 | @Override 14 | public DBWeapon getWeaponById(int id) { 15 | try (Session session = DbFactory.getSessionFactory().openSession()) { 16 | return session.get(DBWeapon.class, id); 17 | } catch (Exception e) { 18 | log.error("SQL ERROR: {}", e.getMessage(), e); 19 | return null; 20 | } 21 | } 22 | 23 | @Override 24 | public List getAllWeapons() { 25 | try (Session session = DbFactory.getSessionFactory().openSession()) { 26 | return session.createQuery("SELECT w FROM DBWeapon w", DBWeapon.class) 27 | .getResultList(); 28 | } catch (Exception e) { 29 | log.error("SQL ERROR: {}", e.getMessage(), e); 30 | return null; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/db/repository/ZoneListRepository.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.db.repository; 2 | 3 | import com.shnok.javaserver.db.DbFactory; 4 | import com.shnok.javaserver.db.entity.DBZoneList; 5 | import com.shnok.javaserver.db.interfaces.ZoneListDao; 6 | import com.shnok.javaserver.model.Point3D; 7 | import com.shnok.javaserver.util.VectorUtils; 8 | import javolution.util.FastMap; 9 | import lombok.extern.log4j.Log4j2; 10 | import org.hibernate.Session; 11 | 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | import static com.shnok.javaserver.config.Configuration.server; 16 | 17 | @Log4j2 18 | public class ZoneListRepository implements ZoneListDao { 19 | @Override 20 | public List getAllZoneList() { 21 | try (Session session = DbFactory.getSessionFactory().openSession()) { 22 | return session.createQuery("select s from DBZoneList s", DBZoneList.class) 23 | .getResultList(); 24 | } catch (Exception e) { 25 | log.error("SQL ERROR: {}", e.getMessage(), e); 26 | return null; 27 | } 28 | } 29 | 30 | public Map getAllZoneMap() { 31 | List zoneLists = getAllZoneList(); 32 | log.debug("Loaded {} zone info(s).", zoneLists.size()); 33 | Map zoneMap = new FastMap<>(); 34 | for(DBZoneList zone : zoneLists) { 35 | Point3D origin = VectorUtils.floorToNearest(zone.getOrigin(), server.geodataNodeSize()); 36 | zone.setOrigX(origin.getX()); 37 | zone.setOrigY(origin.getY()); 38 | zone.setOrigZ(origin.getZ()); 39 | 40 | zoneMap.put(zone.getId(), zone); 41 | } 42 | return zoneMap; 43 | } 44 | 45 | @Override 46 | public DBZoneList getZoneListById(String id) { 47 | try (Session session = DbFactory.getSessionFactory().openSession()) { 48 | return session.get(DBZoneList.class, id); 49 | } catch (Exception e) { 50 | log.error("SQL ERROR: {}", e.getMessage(), e); 51 | return null; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/Packet.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto; 2 | 3 | public abstract class Packet { 4 | protected byte packetType; 5 | protected byte[] packetData; 6 | 7 | public Packet(byte type) { 8 | packetType = type; 9 | } 10 | 11 | public Packet(byte[] data) { 12 | setData(data); 13 | } 14 | 15 | public byte[] getData() { 16 | return packetData; 17 | } 18 | 19 | public void setData(byte[] data) { 20 | packetType = data[0]; 21 | packetData = data; 22 | } 23 | 24 | public byte getType() { 25 | return packetType; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/ReceivablePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.charset.StandardCharsets; 5 | import java.util.Arrays; 6 | 7 | public abstract class ReceivablePacket extends Packet { 8 | private int iterator; 9 | 10 | public ReceivablePacket(byte[] data) { 11 | super(data); 12 | readB(); 13 | } 14 | 15 | protected byte readB() { 16 | return packetData[iterator++]; 17 | } 18 | 19 | protected byte[] readB(int size) { 20 | byte[] readBytes = Arrays.copyOfRange(packetData, iterator, iterator + size); 21 | iterator += size; 22 | return readBytes; 23 | } 24 | 25 | protected int readI() { 26 | byte[] array = new byte[4]; 27 | System.arraycopy(packetData, iterator, array, 0, 4); 28 | iterator += 4; 29 | return ByteBuffer.wrap(array).getInt(); 30 | } 31 | 32 | protected float readF() { 33 | byte[] array = new byte[4]; 34 | System.arraycopy(packetData, iterator, array, 0, 4); 35 | iterator += 4; 36 | return ByteBuffer.wrap(array).getFloat(); 37 | } 38 | 39 | protected String readS() { 40 | byte strLen = readB(); 41 | byte[] data = new byte[strLen]; 42 | System.arraycopy(packetData, iterator, data, 0, strLen); 43 | iterator += strLen; 44 | 45 | return new String(data, 0, strLen, StandardCharsets.UTF_8); 46 | } 47 | 48 | public abstract void handlePacket(); 49 | } 50 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/ClientPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external; 2 | 3 | import com.shnok.javaserver.dto.ReceivablePacket; 4 | import com.shnok.javaserver.thread.GameClientThread; 5 | 6 | public abstract class ClientPacket extends ReceivablePacket { 7 | protected GameClientThread client; 8 | 9 | public ClientPacket(GameClientThread client, byte[] data) { 10 | super(data); 11 | this.client = client; 12 | } 13 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/RequestActionUsePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.ActionFailedPacket; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | import com.shnok.javaserver.thread.GameClientThread; 7 | import lombok.extern.log4j.Log4j2; 8 | 9 | @Log4j2 10 | public class RequestActionUsePacket extends ClientPacket { 11 | 12 | private final int actionId; 13 | 14 | public RequestActionUsePacket(GameClientThread client, byte[] data) { 15 | super(client, data); 16 | actionId = readI(); 17 | 18 | handlePacket(); 19 | } 20 | 21 | @Override 22 | public void handlePacket() { 23 | PlayerInstance activeChar = client.getCurrentPlayer(); 24 | if (activeChar == null) { 25 | return; 26 | } 27 | 28 | // dont do anything if player is dead 29 | if (activeChar.isAlikeDead()) { 30 | client.sendPacket(new ActionFailedPacket()); 31 | return; 32 | } 33 | 34 | // don't do anything if player is confused 35 | if (activeChar.isOutOfControl()) { 36 | client.sendPacket(new ActionFailedPacket()); 37 | return; 38 | } 39 | 40 | switch (actionId) { 41 | case 0: 42 | if (activeChar.isSitting()) { 43 | activeChar.standUp(); 44 | } else { 45 | activeChar.sitDown(); 46 | } 47 | 48 | log.debug("new wait type: {}", activeChar.isSitting() ? "SITTING" : "STANDING"); 49 | 50 | break; 51 | case 1: 52 | if (activeChar.isRunning()) { 53 | activeChar.setRunning(false); 54 | } else { 55 | activeChar.setRunning(true); 56 | } 57 | 58 | log.debug("new move type: {}", activeChar.isRunning() ? "RUNNING" : "WALKING"); 59 | break; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/RequestAttackPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.thread.GameClientThread; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class RequestAttackPacket extends ClientPacket { 9 | private final int targetId; 10 | private final byte attackType; 11 | 12 | public RequestAttackPacket(GameClientThread client, byte[] data) { 13 | super(client, data); 14 | targetId = readI(); 15 | attackType = readB(); 16 | 17 | handlePacket(); 18 | } 19 | 20 | @Override 21 | public void handlePacket() { 22 | // 23 | // //GameObject object = client.getCurrentPlayer().getKnownList().getKnownObjects().get(getTargetId()); 24 | // GameObject object = client.getCurrentPlayer(); 25 | // if(object == null) { 26 | // log.warn("Trying to attack a null object."); 27 | // } 28 | // if(!(object.isEntity())) { 29 | // log.warn("Trying to attack a non-entity object."); 30 | // return; 31 | // } 32 | // if(((Entity)object).getStatus().getCurrentHp() <= 0) { 33 | // log.warn("Trying to attack a dead entity."); 34 | // return; 35 | // } 36 | // 37 | // // ! FOR DEBUG PURPOSE 38 | // int damage = 25; 39 | // ((Entity) object).reduceCurrentHp(damage, client.getCurrentPlayer()); 40 | // boolean critical = false; 41 | // Random r = new Random(); 42 | // if(r.nextInt(2) == 0) { 43 | // critical = true; 44 | // } 45 | // 46 | // // ! FOR DEBUG PURPOSE 47 | // // Notify known list 48 | // ApplyDamagePacket applyDamagePacket = new ApplyDamagePacket( 49 | // client.getCurrentPlayer().getId(), getTargetId(), damage, ((Entity) object).getStatus().getCurrentHp(), critical); 50 | // // Send packet to player's known list 51 | // client.getCurrentPlayer().broadcastPacket(applyDamagePacket); 52 | // // Send packet to player 53 | // client.sendPacket(applyDamagePacket); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/RequestCharacterAnimationPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.ObjectAnimationPacket; 5 | import com.shnok.javaserver.thread.GameClientThread; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public class RequestCharacterAnimationPacket extends ClientPacket { 10 | private final byte animId; 11 | private final float value; 12 | 13 | public RequestCharacterAnimationPacket(GameClientThread client, byte[] data) { 14 | super(client, data); 15 | animId = readB(); 16 | value = readF(); 17 | 18 | handlePacket(); 19 | } 20 | 21 | @Override 22 | public void handlePacket() { 23 | // Notify known list 24 | ObjectAnimationPacket objectAnimationPacket = new ObjectAnimationPacket( 25 | client.getCurrentPlayer().getId(), getAnimId(), getValue()); 26 | client.getCurrentPlayer().broadcastPacket(objectAnimationPacket); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/RequestCharacterMovePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.model.Point3D; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | import com.shnok.javaserver.thread.GameClientThread; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | public class RequestCharacterMovePacket extends ClientPacket { 11 | private final Point3D position = new Point3D(); 12 | 13 | public RequestCharacterMovePacket(GameClientThread client, byte[] data) { 14 | super(client, data); 15 | position.setX(readF()); 16 | position.setY(readF()); 17 | position.setZ(readF()); 18 | 19 | handlePacket(); 20 | } 21 | 22 | @Override 23 | public void handlePacket() { 24 | Point3D newPos = getPosition(); 25 | 26 | PlayerInstance currentPlayer = client.getCurrentPlayer(); 27 | currentPlayer.setPosition(newPos); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/RequestCharacterRotatePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.ObjectRotationPacket; 5 | import com.shnok.javaserver.thread.GameClientThread; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public class RequestCharacterRotatePacket extends ClientPacket { 10 | private final float angle; 11 | 12 | public RequestCharacterRotatePacket(GameClientThread client, byte[] data) { 13 | super(client, data); 14 | angle = readF(); 15 | 16 | handlePacket(); 17 | } 18 | 19 | @Override 20 | public void handlePacket() { 21 | // Notify known list 22 | ObjectRotationPacket objectRotationPacket = new ObjectRotationPacket( 23 | client.getCurrentPlayer().getId(), getAngle()); 24 | client.getCurrentPlayer().broadcastPacket(objectRotationPacket); 25 | } 26 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/RequestSendMessagePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.MessagePacket; 5 | import com.shnok.javaserver.service.GameServerController; 6 | import com.shnok.javaserver.thread.GameClientThread; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | public class RequestSendMessagePacket extends ClientPacket { 11 | private final String message; 12 | 13 | public RequestSendMessagePacket(GameClientThread client, byte[] data) { 14 | super(client, data); 15 | 16 | message = readS(); 17 | 18 | handlePacket(); 19 | } 20 | 21 | @Override 22 | public void handlePacket() { 23 | String message = getMessage(); 24 | 25 | MessagePacket messagePacket = new MessagePacket(client.getAccountName(), message); 26 | GameServerController.getInstance().broadcast(messagePacket); 27 | } 28 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/RequestSetTargetPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.ActionFailedPacket; 5 | import com.shnok.javaserver.enums.PlayerAction; 6 | import com.shnok.javaserver.model.object.entity.Entity; 7 | import com.shnok.javaserver.thread.GameClientThread; 8 | import lombok.Getter; 9 | import lombok.extern.log4j.Log4j2; 10 | 11 | @Log4j2 12 | @Getter 13 | public class RequestSetTargetPacket extends ClientPacket { 14 | private final int targetId; 15 | 16 | public RequestSetTargetPacket(GameClientThread client, byte[] data) { 17 | super(client, data); 18 | 19 | targetId = readI(); 20 | 21 | handlePacket(); 22 | } 23 | 24 | @Override 25 | public void handlePacket() { 26 | if(getTargetId() == -1) { 27 | // Clear target 28 | client.getCurrentPlayer().getAi().setTarget(null); 29 | } else { 30 | //TODO: find entity in all entities if missing in knownlist and add it 31 | 32 | // Check if user is allowed to target entity 33 | if(!client.getCurrentPlayer().getKnownList().knowsObject(getTargetId())) { 34 | log.warn("[{}] Player tried to target an entity outside of this known list with ID [{}]", 35 | client.getCurrentPlayer().getId(), getTargetId()); 36 | client.sendPacket(new ActionFailedPacket(PlayerAction.SetTarget.getValue())); 37 | return; 38 | } 39 | 40 | Entity target = (Entity) client.getCurrentPlayer().getKnownList().getKnownObject(getTargetId()); 41 | 42 | // Set entity target 43 | client.getCurrentPlayer().getAi().setTarget(target); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/authentication/AuthLoginPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.model.network.SessionKey; 5 | import com.shnok.javaserver.thread.GameClientThread; 6 | import com.shnok.javaserver.thread.LoginServerThread; 7 | import lombok.Getter; 8 | import lombok.extern.log4j.Log4j2; 9 | 10 | @Log4j2 11 | @Getter 12 | public class AuthLoginPacket extends ClientPacket { 13 | // loginName + keys must match what the login server used. 14 | private final String account; 15 | private final int playKey1; 16 | private final int playKey2; 17 | private final int loginKey1; 18 | private final int loginKey2; 19 | 20 | public AuthLoginPacket(GameClientThread client, byte[] data) { 21 | super(client, data); 22 | 23 | account = readS().toLowerCase(); 24 | playKey1 = readI(); 25 | playKey2 = readI(); 26 | loginKey1 = readI(); 27 | loginKey2 = readI(); 28 | 29 | handlePacket(); 30 | } 31 | 32 | @Override 33 | public void handlePacket() { 34 | // avoid potential exploits 35 | if (client.getAccountName() == null) { 36 | SessionKey key = new SessionKey(getLoginKey1(), getLoginKey2(), 37 | getPlayKey1(), getPlayKey2()); 38 | 39 | log.info("Received auth request for account: {}.", getAccount()); 40 | // Preventing duplicate login in case client login server socket was disconnected or this packet was not sent yet 41 | if (LoginServerThread.getInstance().addLoggedAccount(getAccount(), client)) { 42 | client.setAccountName(getAccount()); 43 | LoginServerThread.getInstance().addWaitingClientAndSendRequest(getAccount(), client, key); 44 | } else { 45 | client.disconnect(); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/authentication/DisconnectPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.ActionFailedPacket; 5 | import com.shnok.javaserver.dto.external.serverpackets.SystemMessagePacket; 6 | import com.shnok.javaserver.enums.network.SystemMessageId; 7 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 8 | import com.shnok.javaserver.service.AttackStanceManagerService; 9 | import com.shnok.javaserver.thread.GameClientThread; 10 | import lombok.extern.log4j.Log4j2; 11 | 12 | @Log4j2 13 | public class DisconnectPacket extends ClientPacket { 14 | 15 | public DisconnectPacket(GameClientThread client) { 16 | super(client, new byte[1]); 17 | 18 | handlePacket(); 19 | } 20 | 21 | @Override 22 | public void handlePacket() { 23 | // Dont allow leaving if player is fighting 24 | PlayerInstance player = client.getCurrentPlayer(); 25 | if (player == null) { 26 | log.warn("[DisconnectPacket] activeChar null!?"); 27 | return; 28 | } 29 | 30 | // TODO update DB 31 | //player.getInventory().updateDatabase(); 32 | 33 | if (AttackStanceManagerService.getInstance().getAttackStanceTask(player)) { 34 | log.debug("Player {} tried to logout while fighting", player.getName()); 35 | player.sendPacket(new SystemMessagePacket(SystemMessageId.CANT_LOGOUT_WHILE_FIGHTING)); 36 | player.sendPacket(new ActionFailedPacket()); 37 | return; 38 | } 39 | 40 | // Close the connection with the client 41 | player.closeNetConnection(); 42 | //notifyFriends(player); 43 | } 44 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/authentication/ProtocolVersionPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.authentication.KeyPacket; 5 | import com.shnok.javaserver.thread.GameClientThread; 6 | import lombok.Getter; 7 | import lombok.extern.log4j.Log4j2; 8 | 9 | import static com.shnok.javaserver.config.Configuration.server; 10 | 11 | @Log4j2 12 | @Getter 13 | public class ProtocolVersionPacket extends ClientPacket { 14 | private final int version; 15 | public ProtocolVersionPacket(GameClientThread client, byte[] data) { 16 | super(client, data); 17 | version = readI(); 18 | 19 | handlePacket(); 20 | } 21 | 22 | @Override 23 | public void handlePacket() { 24 | if (!server.allowedProtocolVersions().contains(getVersion())) { 25 | log.warn("Received wrong protocol version: {}.", getVersion()); 26 | 27 | KeyPacket pk = new KeyPacket(client.enableCrypt(), false); 28 | client.sendPacket(pk); 29 | client.setProtocolOk(false); 30 | client.setCryptEnabled(true); 31 | client.disconnect(); 32 | } else { 33 | log.debug("Client protocol version is ok: {}.", getVersion()); 34 | 35 | KeyPacket pk = new KeyPacket(client.enableCrypt(), true); 36 | client.sendPacket(pk); 37 | client.setProtocolOk(true); 38 | client.setCryptEnabled(true); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/item/RequestDropItemPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets.item; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.thread.GameClientThread; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class RequestDropItemPacket extends ClientPacket { 9 | private final int itemObjectId; 10 | private final int count; 11 | 12 | public RequestDropItemPacket(GameClientThread client, byte[] data) { 13 | super(client, data); 14 | itemObjectId = readI(); 15 | count = readI(); 16 | } 17 | 18 | @Override 19 | public void handlePacket() { 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/item/RequestInventoryOpenPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets.item; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.item.InventoryItemListPacket; 5 | import com.shnok.javaserver.thread.GameClientThread; 6 | 7 | public class RequestInventoryOpenPacket extends ClientPacket { 8 | public RequestInventoryOpenPacket(GameClientThread client) { 9 | super(client, new byte[1]); 10 | 11 | handlePacket(); 12 | } 13 | 14 | @Override 15 | public void handlePacket() { 16 | InventoryItemListPacket packet = new InventoryItemListPacket(client.getCurrentPlayer(), true); 17 | client.getCurrentPlayer().getInventory().getUpdatedItems(); 18 | client.sendPacket(packet); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/shortcut/RequestShortcutDelPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets.shortcut; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 5 | import com.shnok.javaserver.thread.GameClientThread; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public class RequestShortcutDelPacket extends ClientPacket { 10 | private final int slot; 11 | private final int page; 12 | 13 | public RequestShortcutDelPacket(GameClientThread client, byte[] data) { 14 | super(client, data); 15 | int id = readI(); 16 | slot = id % 12; 17 | page = id / 12; 18 | 19 | handlePacket(); 20 | } 21 | 22 | @Override 23 | public void handlePacket() { 24 | PlayerInstance activeChar = client.getCurrentPlayer(); 25 | if (activeChar == null) { 26 | return; 27 | } 28 | 29 | activeChar.deleteShortCut(slot, page); 30 | // client needs no confirmation. this packet is just to inform the server 31 | } 32 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/clientpackets/shortcut/RequestShortcutRegPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.clientpackets.shortcut; 2 | 3 | import com.shnok.javaserver.dto.external.ClientPacket; 4 | import com.shnok.javaserver.dto.external.serverpackets.shortcut.ShortcutRegisterPacket; 5 | import com.shnok.javaserver.enums.ShortcutType; 6 | import com.shnok.javaserver.model.shortcut.Shortcut; 7 | import com.shnok.javaserver.thread.GameClientThread; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | public class RequestShortcutRegPacket extends ClientPacket { 12 | 13 | private final ShortcutType shortcutType; 14 | private final int id; 15 | private final int slot; 16 | private final int page; 17 | private final int lvl; 18 | private int characterType; // 1 - player, 2 - pet 19 | 20 | public RequestShortcutRegPacket(GameClientThread client, byte[] data) { 21 | super(client, data); 22 | 23 | final int typeId = readI(); 24 | shortcutType = ShortcutType.getById(typeId); 25 | final int tmp = readI(); 26 | slot = tmp % 12; 27 | page = tmp / 12; 28 | id = readI(); 29 | lvl = readI(); 30 | 31 | handlePacket(); 32 | } 33 | 34 | @Override 35 | public void handlePacket() { 36 | if (client.getCurrentPlayer() == null || (page > 10) || (page < 0)) { 37 | return; 38 | } 39 | 40 | final Shortcut sc = new Shortcut(slot, page, shortcutType, id, lvl, characterType); 41 | client.getCurrentPlayer().registerShortCut(sc); 42 | client.sendPacket(new ShortcutRegisterPacket(sc)); 43 | } 44 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ActionAllowedPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class ActionAllowedPacket extends SendablePacket { 7 | public ActionAllowedPacket(byte action) { 8 | super(ServerPacketType.ActionAllowed.getValue()); 9 | writeB(action); 10 | buildPacket(); 11 | } 12 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ActionFailedPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class ActionFailedPacket extends SendablePacket { 7 | public ActionFailedPacket() { 8 | super(ServerPacketType.ActionFailed.getValue()); 9 | writeB((byte) -1); 10 | buildPacket(); 11 | } 12 | 13 | public ActionFailedPacket(byte action) { 14 | super(ServerPacketType.ActionFailed.getValue()); 15 | writeB(action); 16 | buildPacket(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ApplyDamagePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.Hit; 6 | import com.shnok.javaserver.model.object.entity.Entity; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Iterator; 10 | import java.util.List; 11 | 12 | public class ApplyDamagePacket extends SendablePacket { 13 | private final List hits = new ArrayList<>(); 14 | private boolean soulshot = false; 15 | private byte ssGrade = 0; 16 | private final int attackerId; 17 | 18 | public ApplyDamagePacket(int attackerId, boolean soulshot, byte ssGrade) { 19 | super(ServerPacketType.ApplyDamage.getValue()); 20 | this.attackerId = attackerId; 21 | this.soulshot = soulshot; 22 | this.ssGrade = ssGrade; 23 | } 24 | 25 | public boolean hasSoulshot() { 26 | return soulshot; 27 | } 28 | 29 | /** 30 | * Adds hit to the attack (Attacks such as dual dagger/sword/fist has two hits) 31 | * @param target 32 | * @param damage 33 | * @param miss 34 | * @param crit 35 | * @param shld 36 | */ 37 | public void addHit(Entity target, int damage, boolean miss, boolean crit, byte shld) { 38 | hits.add(new Hit(target, damage, miss, crit, shld, soulshot, ssGrade)); 39 | } 40 | 41 | /** 42 | * @return {@code true} if current attack contains at least 1 hit. 43 | */ 44 | public boolean hasHits() { 45 | return !hits.isEmpty(); 46 | } 47 | 48 | /** 49 | * Writes current hit 50 | * @param hit 51 | */ 52 | private void writeHit(Hit hit) { 53 | writeI(hit.getTargetId()); 54 | writeI(hit.getDamage()); 55 | writeI(hit.getFlags()); 56 | } 57 | 58 | public void writeMe() { 59 | final Iterator it = hits.iterator(); 60 | 61 | writeI(attackerId); 62 | 63 | writeB((byte) hits.size()); 64 | while (it.hasNext()) { 65 | writeHit(it.next()); 66 | } 67 | 68 | buildPacket(); 69 | } 70 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/AutoAttackStartPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class AutoAttackStartPacket extends SendablePacket { 7 | public AutoAttackStartPacket(int id) { 8 | super(ServerPacketType.AutoAttackStart.getValue()); 9 | writeI(id); 10 | buildPacket(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/AutoAttackStopPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class AutoAttackStopPacket extends SendablePacket { 7 | public AutoAttackStopPacket(int id) { 8 | super(ServerPacketType.AutoAttackStop.getValue()); 9 | writeI(id); 10 | buildPacket(); 11 | } 12 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ChangeMoveTypePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.object.MovableObject; 6 | 7 | public class ChangeMoveTypePacket extends SendablePacket { 8 | 9 | public static final int WALK = 0; 10 | public static final int RUN = 1; 11 | 12 | public ChangeMoveTypePacket(MovableObject obj) { 13 | super(ServerPacketType.ChangeMoveType.getValue()); 14 | writeI(obj.getId()); 15 | writeI(obj.isRunning() ? RUN : WALK); 16 | buildPacket(); 17 | } 18 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ChangeWaitTypePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | 7 | public class ChangeWaitTypePacket extends SendablePacket { 8 | 9 | public static final int WT_SITTING = 0; 10 | public static final int WT_STANDING = 1; 11 | public static final int WT_START_FAKEDEATH = 2; 12 | public static final int WT_STOP_FAKEDEATH = 3; 13 | 14 | public ChangeWaitTypePacket(PlayerInstance owner, int newMoveType) { 15 | super(ServerPacketType.ChangeWaitType.getValue()); 16 | 17 | if (owner == null) { 18 | return; 19 | } 20 | 21 | writeI(owner.getId()); 22 | writeI(newMoveType); 23 | writeF(owner.getPosX()); 24 | writeF(owner.getPosY()); 25 | writeF(owner.getPosZ()); 26 | 27 | buildPacket(); 28 | } 29 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/EntitySetTargetPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class EntitySetTargetPacket extends SendablePacket { 7 | public EntitySetTargetPacket(int id, int targetId) { 8 | super(ServerPacketType.EntitySetTarget.getValue()); 9 | writeI(id); 10 | writeI(targetId); 11 | buildPacket(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/MessagePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class MessagePacket extends SendablePacket { 7 | private String text; 8 | private String sender; 9 | 10 | public MessagePacket(String sender, String text) { 11 | super(ServerPacketType.MessagePacket.getValue()); 12 | 13 | setText(text); 14 | setSender(sender); 15 | buildMessageData(); 16 | } 17 | 18 | public void setSender(String sender) { 19 | this.sender = sender; 20 | } 21 | 22 | public void setText(String text) { 23 | this.text = text; 24 | } 25 | 26 | public void buildMessageData() { 27 | writeS(sender); 28 | writeS(text); 29 | buildPacket(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/NpcInfoPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.object.entity.NpcInstance; 6 | 7 | public class NpcInfoPacket extends SendablePacket { 8 | public NpcInfoPacket(NpcInstance npc) { 9 | super(ServerPacketType.NpcInfo.getValue()); 10 | 11 | writeI(npc.getId()); 12 | writeI(npc.getTemplate().getNpcId()); 13 | writeF(npc.getPosition().getHeading()); 14 | writeF(npc.getPosX()); 15 | writeF(npc.getPosY()); 16 | writeF(npc.getPosZ()); 17 | // Stats 18 | writeI((int) npc.getStat().getMoveSpeed()); 19 | writeI((int) npc.getStat().getWalkSpeed()); 20 | writeI((int) npc.getPAtkSpd()); 21 | writeI((int) npc.getMAtkSpd()); 22 | // Status 23 | writeI(npc.getLevel()); 24 | writeI((int) npc.getCurrentHp()); 25 | writeI(npc.getMaxHp()); 26 | 27 | writeI(npc.isRunning() ? 1 : 0); 28 | 29 | buildPacket(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ObjectAnimationPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class ObjectAnimationPacket extends SendablePacket { 7 | 8 | public ObjectAnimationPacket(int id, byte animId, float value) { 9 | super(ServerPacketType.ObjectAnimation.getValue()); 10 | writeI(id); 11 | writeB(animId); 12 | writeF(value); 13 | buildPacket(); 14 | } 15 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ObjectDirectionPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.Point3D; 6 | 7 | public class ObjectDirectionPacket extends SendablePacket { 8 | public ObjectDirectionPacket(int id, float speed, Point3D direction) { 9 | super(ServerPacketType.ObjectMoveDirection.getValue()); 10 | writeI(id); 11 | writeI((int) speed); 12 | writeF(direction.getX()); 13 | writeF(direction.getY()); 14 | writeF(direction.getZ()); 15 | buildPacket(); 16 | } 17 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ObjectMoveToPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.Point3D; 6 | 7 | public class ObjectMoveToPacket extends SendablePacket { 8 | public ObjectMoveToPacket(int id, Point3D pos, float speed, boolean walking) { 9 | super(ServerPacketType.ObjectMoveTo.getValue()); 10 | 11 | writeI(id); 12 | writeF(pos.getX()); 13 | writeF(pos.getY()); 14 | writeF(pos.getZ()); 15 | writeI((int) speed); 16 | writeB(walking ? (byte) 1 : (byte) 0); 17 | buildPacket(); 18 | } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ObjectPositionPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.Point3D; 6 | 7 | public class ObjectPositionPacket extends SendablePacket { 8 | public ObjectPositionPacket(int id, Point3D pos) { 9 | super(ServerPacketType.ObjectPosition.getValue()); 10 | 11 | writeI(id); 12 | writeF(pos.getX()); 13 | writeF(pos.getY()); 14 | writeF(pos.getZ()); 15 | buildPacket(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ObjectRotationPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class ObjectRotationPacket extends SendablePacket { 7 | public ObjectRotationPacket(int id, float angle) { 8 | super(ServerPacketType.ObjectRotation.getValue()); 9 | writeI(id); 10 | writeF(angle); 11 | buildPacket(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/RemoveObjectPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class RemoveObjectPacket extends SendablePacket { 7 | public RemoveObjectPacket(int id) { 8 | super(ServerPacketType.RemoveObject.getValue()); 9 | 10 | writeI(id); 11 | buildPacket(); 12 | } 13 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/ServerClosePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | 7 | public class ServerClosePacket extends SendablePacket { 8 | // Kick user 9 | public ServerClosePacket() { 10 | super(ServerPacketType.ServerClose.getValue()); 11 | 12 | buildPacket(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/SocialActionPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | public class SocialActionPacket { 4 | } 5 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/UserInfoPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.enums.item.ItemSlot; 6 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 7 | 8 | import java.util.Objects; 9 | 10 | import static com.shnok.javaserver.dto.external.serverpackets.PlayerInfoPacket.PAPERDOLL_ORDER; 11 | 12 | public class UserInfoPacket extends SendablePacket { 13 | public UserInfoPacket(PlayerInstance player) { 14 | super(ServerPacketType.UserInfo.getValue()); 15 | 16 | writeI(player.getId()); 17 | writeS(player.getName()); 18 | writeB(player.getTemplate().getClassId().getId()); 19 | writeB(player.getTemplate().getClassId().isMage() ? (byte) 1 : (byte) 0); 20 | writeF(player.getPosition().getHeading()); 21 | writeF(player.getPosX()); 22 | writeF(player.getPosY()); 23 | writeF(player.getPosZ()); 24 | // Status 25 | writeI(player.getLevel()); 26 | writeI((int) player.getCurrentHp()); 27 | writeI(player.getMaxHp()); 28 | // Stats 29 | writeI((int) player.getMoveSpeed()); 30 | writeI((int) player.getWalkSpeed()); 31 | writeI((int) player.getPAtkSpd()); 32 | writeI(player.getMAtkSpd()); 33 | // Appearance 34 | writeF(player.getTemplate().getCollisionHeight()); 35 | writeF(player.getTemplate().getCollisionRadius()); 36 | writeB(player.getTemplate().getRace().getValue()); 37 | writeB(player.getAppearance().isSex() ? (byte) 1 : (byte) 0); 38 | writeB(player.getAppearance().getFace()); 39 | writeB(player.getAppearance().getHairStyle()); 40 | writeB(player.getAppearance().getHairColor()); 41 | 42 | // Gear 43 | for (byte slot : PAPERDOLL_ORDER) { 44 | writeI(player.getInventory().getEquippedItemId(Objects.requireNonNull(ItemSlot.getSlot(slot)))); 45 | } 46 | 47 | writeI(player.isRunning() ? 1 : 0); 48 | 49 | buildPacket(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/authentication/GameTimePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.service.GameTimeControllerService; 6 | 7 | import static com.shnok.javaserver.config.Configuration.server; 8 | 9 | public class GameTimePacket extends SendablePacket { 10 | public GameTimePacket() { 11 | super(ServerPacketType.GameTimePacket.getValue()); 12 | 13 | writeL(GameTimeControllerService.getInstance().gameTicks); 14 | writeI(GameTimeControllerService.getInstance().getTickDurationMs()); 15 | writeI(server.dayDurationMin()); 16 | 17 | buildPacket(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/authentication/KeyPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class KeyPacket extends SendablePacket { 7 | public KeyPacket(byte[] key, boolean allowed) { 8 | super(ServerPacketType.Key.getValue()); 9 | 10 | writeB((byte) key.length); 11 | writeB(key); 12 | writeB(allowed ? (byte) 1 : (byte) 0); 13 | 14 | buildPacket(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/authentication/LeaveWorldPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class LeaveWorldPacket extends SendablePacket { 7 | public LeaveWorldPacket() { 8 | super(ServerPacketType.LeaveWorld.getValue()); 9 | 10 | writeB((byte) 0); 11 | 12 | buildPacket(); 13 | } 14 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/authentication/LoginFailPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.LoginFailReason; 5 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 6 | 7 | public class LoginFailPacket extends SendablePacket { 8 | public LoginFailPacket(LoginFailReason loginFailReason) { 9 | super(ServerPacketType.LoginFail.getValue()); 10 | writeB((byte) loginFailReason.getCode()); 11 | 12 | buildPacket(); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/authentication/PingPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class PingPacket extends SendablePacket { 7 | public PingPacket() { 8 | super(ServerPacketType.Ping.getValue()); 9 | setData(new byte[]{ServerPacketType.Ping.getValue(), 0x02}); 10 | buildPacket(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/authentication/RestartResponsePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.authentication; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | 6 | public class RestartResponsePacket extends SendablePacket { 7 | 8 | public RestartResponsePacket() { 9 | super(ServerPacketType.RestartResponse.getValue()); 10 | 11 | writeI((byte) 1); 12 | writeS("Ora ora!"); 13 | 14 | buildPacket(); 15 | } 16 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/item/AbstractItemPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.item; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.model.item.ItemInfo; 5 | import com.shnok.javaserver.model.object.ItemInstance; 6 | 7 | import java.util.List; 8 | 9 | public abstract class AbstractItemPacket extends SendablePacket { 10 | public AbstractItemPacket(byte type) { 11 | super(type); 12 | } 13 | 14 | protected void writeItem(ItemInstance item) { 15 | writeItem(new ItemInfo(item)); 16 | } 17 | 18 | protected void writeItem(ItemInfo item) { 19 | writeI(item.getObjectId()); // ObjectId 20 | writeI(item.getItem().getId()); // ItemId 21 | writeB((byte) item.getLocation()); // Inventory? Warehouse? 22 | writeI(item.getSlot()); // Slot 23 | writeI((int) item.getCount()); // Quantity 24 | writeB(item.getCategory()); // Item Type 2 : 00-weapon, 01-shield/armor, 02-ring/earring/necklace, 03-questitem, 04-adena, 05-item 25 | writeB(item.getEquipped()); // Equipped : 00-No, 01-yes 26 | if(item.getCategory() <= 2) { 27 | writeI(item.getItem().getBodyPart().getValue()); 28 | } else { 29 | writeI(0); 30 | } 31 | writeI(item.getEnchant()); // Enchant level 32 | writeL(item.getTime()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/item/InventoryItemListPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.item; 2 | 3 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 4 | import com.shnok.javaserver.model.object.ItemInstance; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | import lombok.Getter; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | @Getter 12 | public class InventoryItemListPacket extends AbstractItemPacket { 13 | private final boolean showWindow; 14 | private final List items; 15 | 16 | public InventoryItemListPacket(PlayerInstance player, boolean showWindow) { 17 | super(ServerPacketType.InventoryItemList.getValue()); 18 | 19 | this.showWindow = showWindow; 20 | this.items = new ArrayList<>(); 21 | 22 | for (ItemInstance item : player.getInventory().getItems()) { 23 | if (!item.isQuestItem()) { 24 | items.add(item); 25 | } 26 | } 27 | 28 | writeMe(); 29 | buildPacket(); 30 | } 31 | 32 | public void writeMe() { 33 | writeB((byte) (showWindow ? 0x01 : 0x00)); 34 | writeI(items.size()); 35 | items.forEach(this::writeItem); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/item/InventoryUpdatePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.item; 2 | 3 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 4 | import com.shnok.javaserver.model.item.ItemInfo; 5 | import com.shnok.javaserver.model.object.ItemInstance; 6 | import javolution.util.FastList; 7 | 8 | import java.util.List; 9 | 10 | public class InventoryUpdatePacket extends AbstractItemPacket { 11 | 12 | private final List items; 13 | 14 | public InventoryUpdatePacket(List items) { 15 | super(ServerPacketType.InventoryUpdate.getValue()); 16 | this.items = new FastList<>(); 17 | 18 | addItems(items); 19 | } 20 | 21 | public void addItem(ItemInstance item) { 22 | if (item != null) { 23 | items.add(new ItemInfo(item)); 24 | } 25 | } 26 | 27 | public void addNewItem(ItemInstance item) { 28 | if (item != null) { 29 | items.add(new ItemInfo(item, 1)); 30 | } 31 | } 32 | 33 | public void addModifiedItem(ItemInstance item) { 34 | if (item != null) { 35 | items.add(new ItemInfo(item, 2)); 36 | } 37 | } 38 | 39 | public void addRemovedItem(ItemInstance item) { 40 | if (item != null) { 41 | items.add(new ItemInfo(item, 3)); 42 | } 43 | } 44 | 45 | public void addItems(List items) { 46 | if (items != null) { 47 | for (ItemInstance item : items) { 48 | if (item != null) { 49 | this.items.add(new ItemInfo(item)); 50 | } 51 | } 52 | } 53 | } 54 | 55 | public void writeMe() { 56 | writeI(items.size()); 57 | 58 | for (ItemInfo item : items) { 59 | writeI(item.getChange()); 60 | writeItem(item); 61 | } 62 | 63 | buildPacket(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/shortcut/ShortcutInitPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.shortcut; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | import com.shnok.javaserver.model.shortcut.Shortcut; 7 | 8 | public class ShortcutInitPacket extends SendablePacket { 9 | 10 | public ShortcutInitPacket(PlayerInstance owner) { 11 | super(ServerPacketType.ShortcutInit.getValue()); 12 | 13 | if (owner == null) { 14 | return; 15 | } 16 | 17 | Shortcut[] shortCuts = owner.getAllShortCuts(); 18 | 19 | writeI(shortCuts.length); 20 | 21 | for (Shortcut sc : shortCuts) { 22 | writeI(sc.getType().getValue()); 23 | writeI(sc.getSlot() + (sc.getPage() * 12)); 24 | 25 | switch (sc.getType()) { 26 | case ITEM: // 1 27 | writeI(sc.getId()); 28 | break; 29 | case SKILL: // 2 30 | writeI(sc.getId()); 31 | writeI(sc.getLevel()); 32 | break; 33 | case ACTION: // 3 34 | writeI(sc.getId()); 35 | break; 36 | case MACRO: // 4 37 | writeI(sc.getId()); 38 | break; 39 | case RECIPE: // 5 40 | writeI(sc.getId()); 41 | break; 42 | default: 43 | writeI(sc.getId()); 44 | } 45 | } 46 | 47 | buildPacket(); 48 | } 49 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/external/serverpackets/shortcut/ShortcutRegisterPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.external.serverpackets.shortcut; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.external.ServerPacketType; 5 | import com.shnok.javaserver.model.shortcut.Shortcut; 6 | 7 | public class ShortcutRegisterPacket extends SendablePacket { 8 | public ShortcutRegisterPacket(Shortcut shortcut) { 9 | super(ServerPacketType.ShortcutRegister.getValue()); 10 | 11 | writeI(shortcut.getType().getValue()); 12 | writeI(shortcut.getSlot() + (shortcut.getPage() * 12)); 13 | switch (shortcut.getType()) 14 | { 15 | case ITEM: // 1 16 | writeI(shortcut.getId()); 17 | break; 18 | case SKILL: // 2 19 | writeI(shortcut.getId()); 20 | writeI(shortcut.getLevel()); 21 | break; 22 | case ACTION: // 3 23 | writeI(shortcut.getId()); 24 | break; 25 | case MACRO: // 4 26 | writeI(shortcut.getId()); 27 | break; 28 | case RECIPE: // 5 29 | writeI(shortcut.getId()); 30 | break; 31 | default: 32 | writeI(shortcut.getId()); 33 | } 34 | 35 | writeI(1); 36 | 37 | buildPacket(); 38 | } 39 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/LoginServerPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal; 2 | 3 | import com.shnok.javaserver.dto.ReceivablePacket; 4 | import com.shnok.javaserver.thread.LoginServerThread; 5 | 6 | public abstract class LoginServerPacket extends ReceivablePacket { 7 | protected LoginServerThread loginserver; 8 | 9 | public LoginServerPacket(LoginServerThread loginserver, byte[] data) { 10 | super(data); 11 | this.loginserver = loginserver; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/gameserver/AuthRequestPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.gameserver; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.internal.GameServerPacketType; 5 | 6 | import java.util.List; 7 | 8 | public class AuthRequestPacket extends SendablePacket { 9 | public AuthRequestPacket(int id, boolean acceptAlternate, byte[] hexid, int port, int maxplayer, 10 | List subnets, List hosts) { 11 | super(GameServerPacketType.AuthRequest.getValue()); 12 | 13 | writeB((byte) id); 14 | writeB(acceptAlternate ? (byte) 0x01 : (byte) 0x00); 15 | writeI(port); 16 | writeI(maxplayer); 17 | writeI(hexid.length); 18 | writeB(hexid); 19 | writeI(subnets.size()); 20 | 21 | for (int i = 0; i < subnets.size(); i++) { 22 | writeS(subnets.get(i)); 23 | writeS(hosts.get(i)); 24 | } 25 | 26 | buildPacket(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/gameserver/BlowFishKeyPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.gameserver; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.internal.GameServerPacketType; 5 | import lombok.extern.log4j.Log4j2; 6 | 7 | import javax.crypto.Cipher; 8 | import java.security.interfaces.RSAPublicKey; 9 | import java.util.Arrays; 10 | 11 | import static com.shnok.javaserver.config.Configuration.server; 12 | 13 | @Log4j2 14 | public class BlowFishKeyPacket extends SendablePacket { 15 | public BlowFishKeyPacket(byte[] blowfishKey, RSAPublicKey publicKey) { 16 | super(GameServerPacketType.BlowFishKey.getValue()); 17 | 18 | try { 19 | if(server.printCryptography()) { 20 | log.debug("Decrypted blowfish key [{}]: {}", blowfishKey.length, Arrays.toString(blowfishKey)); 21 | } 22 | 23 | final Cipher rsaCipher = Cipher.getInstance(server.rsaPaddingMode()); 24 | rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey); 25 | byte[] encrypted = rsaCipher.doFinal(blowfishKey); 26 | writeB((byte) 0); 27 | writeB((byte) 0); 28 | writeI(encrypted.length); 29 | writeB(encrypted); 30 | 31 | if(server.printCryptography()) { 32 | log.debug("Encrypted blowfish key [{}]: {}", encrypted.length, Arrays.toString(encrypted)); 33 | } 34 | buildPacket(); 35 | } catch (Exception e) { 36 | log.error("Error While encrypting blowfish key for transmision (Crypt error): " + e.getMessage(), e); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/gameserver/PlayerAuthRequestPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.gameserver; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.internal.GameServerPacketType; 5 | import com.shnok.javaserver.model.network.SessionKey; 6 | 7 | public class PlayerAuthRequestPacket extends SendablePacket { 8 | public PlayerAuthRequestPacket(String account, SessionKey key) { 9 | super(GameServerPacketType.PlayerAuthRequest.getValue()); 10 | 11 | writeS(account); 12 | writeI(key.playOkID1); 13 | writeI(key.playOkID2); 14 | writeI(key.loginOkID1); 15 | writeI(key.loginOkID2); 16 | 17 | buildPacket(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/gameserver/PlayerInGamePacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.gameserver; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.internal.GameServerPacketType; 5 | 6 | import java.util.List; 7 | 8 | public class PlayerInGamePacket extends SendablePacket { 9 | public PlayerInGamePacket(String player) { 10 | super(GameServerPacketType.PlayerInGame.getValue()); 11 | 12 | writeI(1); 13 | writeS(player); 14 | 15 | buildPacket(); 16 | } 17 | 18 | public PlayerInGamePacket(List players) { 19 | super(GameServerPacketType.PlayerInGame.getValue()); 20 | 21 | writeI(players.size()); 22 | players.forEach(this::writeS); 23 | 24 | buildPacket(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/gameserver/PlayerLogoutPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.gameserver; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.internal.GameServerPacketType; 5 | 6 | public class PlayerLogoutPacket extends SendablePacket { 7 | public PlayerLogoutPacket(String player) { 8 | super(GameServerPacketType.PlayerLogout.getValue()); 9 | 10 | writeS(player); 11 | 12 | buildPacket(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/gameserver/ReplyCharactersPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.gameserver; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.internal.GameServerPacketType; 5 | 6 | public class ReplyCharactersPacket extends SendablePacket { 7 | public ReplyCharactersPacket(String account, int charCount) { 8 | super(GameServerPacketType.ReplyCharacters.getValue()); 9 | 10 | writeS(account); 11 | writeB((byte) charCount); 12 | 13 | buildPacket(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/gameserver/ServerStatusPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.gameserver; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.packettypes.internal.GameServerPacketType; 5 | 6 | import java.util.ArrayList; 7 | 8 | public class ServerStatusPacket extends SendablePacket { 9 | private final ArrayList attributes; 10 | 11 | // Attributes 12 | public static final int SERVER_LIST_STATUS = 0x00; 13 | public static final int MAX_PLAYERS = 0x01; 14 | 15 | // Server Status 16 | public static final int STATUS_LIGHT = 0x00; 17 | public static final int STATUS_NORMAL = 0x01; 18 | public static final int STATUS_HEAVY = 0x02; 19 | public static final int STATUS_FULL = 0x03; 20 | public static final int STATUS_DOWN = 0x04; 21 | public static final int STATUS_GM_ONLY = 0x05; 22 | 23 | public static final String[] STATUS_STRING = { 24 | "Light", 25 | "Normal", 26 | "Heavy", 27 | "Full", 28 | "Down", 29 | "Gm Only" 30 | }; 31 | 32 | public ServerStatusPacket() { 33 | super(GameServerPacketType.ServerStatus.getValue()); 34 | attributes = new ArrayList<>(); 35 | } 36 | 37 | public void build() { 38 | writeB((byte) 0); 39 | writeB((byte) 0); 40 | writeI(attributes.size()); 41 | for (Attribute temp : attributes) { 42 | writeI(temp.id); 43 | writeI(temp.value); 44 | } 45 | 46 | buildPacket(); 47 | } 48 | 49 | public void addAttribute(int id, int value) { 50 | attributes.add(new Attribute(id, value)); 51 | } 52 | 53 | static class Attribute { 54 | public int id; 55 | public int value; 56 | 57 | Attribute(int pId, int pValue) { 58 | id = pId; 59 | value = pValue; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/loginserver/KickPlayerPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.loginserver; 2 | 3 | import com.shnok.javaserver.dto.internal.LoginServerPacket; 4 | import com.shnok.javaserver.thread.LoginServerThread; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class KickPlayerPacket extends LoginServerPacket { 9 | private final String account; 10 | 11 | public KickPlayerPacket(LoginServerThread loginserver, byte[] data) { 12 | super(loginserver, data); 13 | 14 | account = readS(); 15 | 16 | handlePacket(); 17 | } 18 | 19 | @Override 20 | public void handlePacket() { 21 | loginserver.kickPlayer(getAccount()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/loginserver/LoginServerFailPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.loginserver; 2 | 3 | import com.shnok.javaserver.dto.internal.LoginServerPacket; 4 | import com.shnok.javaserver.enums.LoginServerFailReason; 5 | import com.shnok.javaserver.thread.LoginServerThread; 6 | import lombok.Getter; 7 | import lombok.extern.log4j.Log4j2; 8 | 9 | @Log4j2 10 | @Getter 11 | public class LoginServerFailPacket extends LoginServerPacket { 12 | private final int failReason; 13 | 14 | public LoginServerFailPacket(LoginServerThread loginserver, byte[] data) { 15 | super(loginserver, data); 16 | 17 | readB(); 18 | readB(); 19 | failReason = readI(); 20 | } 21 | 22 | @Override 23 | public void handlePacket() { 24 | LoginServerFailReason failReason = LoginServerFailReason.fromValue(getFailReason()); 25 | log.error("Registration Failed: {}", failReason); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/dto/internal/loginserver/RequestCharactersPacket.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.dto.internal.loginserver; 2 | 3 | import com.shnok.javaserver.db.entity.DBCharacter; 4 | import com.shnok.javaserver.db.repository.CharacterRepository; 5 | import com.shnok.javaserver.dto.internal.LoginServerPacket; 6 | import com.shnok.javaserver.dto.internal.gameserver.ReplyCharactersPacket; 7 | import com.shnok.javaserver.thread.LoginServerThread; 8 | import lombok.Getter; 9 | import lombok.extern.log4j.Log4j2; 10 | 11 | import java.util.List; 12 | 13 | import static com.shnok.javaserver.config.Configuration.server; 14 | 15 | @Log4j2 16 | @Getter 17 | public class RequestCharactersPacket extends LoginServerPacket { 18 | private final String account; 19 | 20 | public RequestCharactersPacket(LoginServerThread loginserver, byte[] data) { 21 | super(loginserver, data); 22 | 23 | account = readS(); 24 | 25 | handlePacket(); 26 | } 27 | 28 | @Override 29 | public void handlePacket() { 30 | String account = getAccount().toLowerCase(); 31 | 32 | List characters = CharacterRepository.getInstance().getCharactersForAccount(account); 33 | 34 | log.info("Account {} have {} character(s).", account, characters.size()); 35 | 36 | if(characters.isEmpty() && server.createRandomCharacter()) { 37 | for(int i = 0; i < 3; i ++) { 38 | CharacterRepository.getInstance().createRandomCharForAccount(account); 39 | } 40 | 41 | characters = CharacterRepository.getInstance().getCharactersForAccount(account); 42 | 43 | log.info("Account {} have {} character(s).", account, characters.size()); 44 | } 45 | 46 | loginserver.sendPacket(new ReplyCharactersPacket(account, characters.size())); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/EntityAnimation.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum EntityAnimation { 4 | Wait((byte) 0), 5 | Walk((byte) 1), 6 | Run((byte) 2), 7 | Die((byte) 3), 8 | Attack((byte) 4), 9 | AttackWait((byte) 5); 10 | 11 | private final byte value; 12 | 13 | EntityAnimation(byte value) { 14 | this.value = value; 15 | } 16 | 17 | public byte getValue() { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/EntityMovingReason.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum EntityMovingReason { 4 | Walking, 5 | Running, 6 | Teleporting 7 | } 8 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/Event.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum Event { 4 | THINK, 5 | DEAD, 6 | ARRIVED, 7 | ATTACKED, 8 | FORGET_OBJECT, 9 | READY_TO_ACT, 10 | CANCEL 11 | } 12 | 13 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/Intention.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum Intention { 4 | INTENTION_IDLE, 5 | INTENTION_WAITING, 6 | INTENTION_MOVE_TO, 7 | INTENTION_ATTACK, 8 | INTENTION_FOLLOW, 9 | INTENTION_REST 10 | } 11 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/ItemLocation.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum ItemLocation { 4 | VOID((byte) 0), 5 | EQUIPPED((byte) 1), 6 | INVENTORY((byte) 2), 7 | WAREHOUSE((byte) 3); 8 | 9 | private final byte value; 10 | 11 | ItemLocation(byte value) { 12 | this.value = value; 13 | } 14 | 15 | public byte getValue() { 16 | return value; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/LoginServerFailReason.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public enum LoginServerFailReason { 7 | REASON_INVALID_GAME_SERVER_VERSION(0), 8 | 9 | REASON_IP_BANNED(1), 10 | 11 | REASON_IP_RESERVED(2), 12 | 13 | REASON_WRONG_HEXID(3), 14 | 15 | REASON_ID_RESERVED(4), 16 | 17 | REASON_NO_FREE_ID(5), 18 | 19 | NOT_AUTHED(6), 20 | 21 | REASON_ALREADY_LOGGED_IN(7); 22 | private final int _code; 23 | 24 | LoginServerFailReason(int code) { 25 | _code = code; 26 | } 27 | 28 | public final int getCode() { 29 | return _code; 30 | } 31 | 32 | private static final Map BY_VALUE = new HashMap<>(); 33 | 34 | static { 35 | for (LoginServerFailReason type : values()) { 36 | BY_VALUE.put(type.getCode(), type); 37 | } 38 | } 39 | 40 | public static LoginServerFailReason fromValue(int value) { 41 | LoginServerFailReason result = BY_VALUE.get(value); 42 | if (result == null) { 43 | throw new IllegalArgumentException("Invalid byte value for ClientPacketType: " + value); 44 | } 45 | return result; 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/MoveType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum MoveType { 4 | WALK, 5 | RUN, 6 | FAST_SWIM, 7 | SLOW_SWIM, 8 | FAST_FLY, 9 | SLOW_FLY 10 | } 11 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/NpcType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum NpcType { 4 | L2Boss, 5 | L2ClassMaster, 6 | L2FriendlyMob, 7 | L2Guard, 8 | L2Merchant, 9 | L2Minion, 10 | L2Monster, 11 | L2Npc, 12 | L2NpcWalker, 13 | L2Pet, 14 | L2Teleporter, 15 | L2Trainer, 16 | L2Warehouse, 17 | L2Adventurer, 18 | L2VillageMaster 19 | } 20 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/PlayerAction.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum PlayerAction { 4 | SetTarget((byte) 0x00), 5 | AutoAttack((byte) 0x01), 6 | Move((byte) 0x02); 7 | 8 | private final byte value; 9 | 10 | PlayerAction(byte value) { 11 | this.value = value; 12 | } 13 | 14 | public byte getValue() { 15 | return value; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/PlayerCondOverride.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public enum PlayerCondOverride { 7 | MAX_STATS_VALUE(0, "Overrides maximum states conditions"), 8 | ITEM_CONDITIONS(1, "Overrides item usage conditions"), 9 | SKILL_CONDITIONS(2, "Overrides skill usage conditions"), 10 | ZONE_CONDITIONS(3, "Overrides zone conditions"), 11 | CASTLE_CONDITIONS(4, "Overrides castle conditions"), 12 | FORTRESS_CONDITIONS(5, "Overrides fortress conditions"), 13 | CLANHALL_CONDITIONS(6, "Overrides clan hall conditions"), 14 | FLOOD_CONDITIONS(7, "Overrides floods conditions"), 15 | CHAT_CONDITIONS(8, "Overrides chat conditions"), 16 | INSTANCE_CONDITIONS(9, "Overrides instance conditions"), 17 | QUEST_CONDITIONS(10, "Overrides quest conditions"), 18 | DEATH_PENALTY(11, "Overrides death penalty conditions"), 19 | DESTROY_ALL_ITEMS(12, "Overrides item destroy conditions"), 20 | SEE_ALL_PLAYERS(13, "Overrides the conditions to see hidden players"), 21 | TARGET_ALL(14, "Overrides target conditions"), 22 | DROP_ALL_ITEMS(15, "Overrides item drop conditions"); 23 | 24 | private final int mask; 25 | private final String description; 26 | 27 | PlayerCondOverride(int id, String descr) { 28 | mask = 1 << id; 29 | description = descr; 30 | } 31 | 32 | public static PlayerCondOverride getCondOverride(int ordinal) { 33 | try { 34 | return values()[ordinal]; 35 | } catch (Exception e) { 36 | return null; 37 | } 38 | } 39 | 40 | public static long getAllExceptionsMask() { 41 | long result = 0L; 42 | for (PlayerCondOverride ex : values()) { 43 | result |= ex.getMask(); 44 | } 45 | return result; 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/Race.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | public enum Race { 4 | human((byte) 0), 5 | elf((byte) 1), 6 | darkelf((byte) 2), 7 | orc((byte) 3), 8 | dwarf((byte) 4); 9 | 10 | private final byte value; 11 | 12 | Race(byte value) { 13 | this.value = value; 14 | } 15 | 16 | public byte getValue() { 17 | return value; 18 | } 19 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/ShortcutType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public enum ShortcutType { 7 | NONE(0), 8 | ITEM(1), 9 | SKILL(2), 10 | ACTION(3), 11 | MACRO(4), 12 | RECIPE(5), 13 | BOOKMARK(6); 14 | 15 | private final int value; 16 | 17 | ShortcutType(int value) { 18 | this.value = value; 19 | } 20 | 21 | public static ShortcutType getById(int id) { 22 | for (ShortcutType type : values()) { 23 | if (type.value == id) { 24 | return type; 25 | } 26 | } 27 | throw new IllegalArgumentException("No ClassId with id " + id); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/ArmorType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum ArmorType { 4 | none((byte) 0), 5 | light((byte) 1), 6 | heavy((byte) 2), 7 | magic((byte) 3), 8 | pet((byte) 4); 9 | 10 | private final byte value; 11 | 12 | ArmorType(byte value) { 13 | this.value = value; 14 | } 15 | 16 | public byte getValue() { 17 | return value; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/ConsumeType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum ConsumeType { 4 | stackable, 5 | asset, 6 | normal 7 | } 8 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/EtcItemType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum EtcItemType { 4 | none((byte) 0), 5 | arrow((byte) 1), 6 | material((byte) 2), 7 | pet_collar((byte) 3), 8 | potion((byte) 4), 9 | recipe((byte) 5), 10 | scroll((byte) 6), 11 | quest((byte) 7), 12 | money((byte) 8), 13 | other((byte) 9), 14 | spellbook((byte) 10), 15 | seed((byte) 11), 16 | shot((byte) 12), 17 | herb((byte) 13); 18 | 19 | private final byte value; 20 | 21 | EtcItemType(byte value) { 22 | this.value = value; 23 | } 24 | 25 | public byte getValue() { 26 | return value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/Grade.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum Grade { 4 | none((byte) 0), 5 | d((byte) 1), 6 | c((byte) 2), 7 | b((byte) 3), 8 | a((byte) 4), 9 | s((byte) 5); 10 | 11 | private final byte value; 12 | 13 | Grade(byte value) { 14 | this.value = value; 15 | } 16 | 17 | public byte getValue() { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/ItemCategory.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum ItemCategory { 4 | //00-weapon, 01-shield/armor, 02-ring/earring/necklace, 03-questitem, 04-adena, 05-item 5 | weapon((byte) 0), 6 | shield_armor((byte) 1), 7 | jewel((byte) 2), 8 | quest_item((byte) 3), 9 | adena((byte) 4), 10 | item((byte) 5); 11 | 12 | private final byte value; 13 | 14 | ItemCategory(byte value) { 15 | this.value = value; 16 | } 17 | 18 | public byte getValue() { 19 | return value; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/ItemSlot.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum ItemSlot { 4 | none((byte) 0), 5 | head((byte) 1), 6 | chest((byte) 2), 7 | legs((byte) 3), 8 | fullarmor((byte) 4), 9 | gloves((byte) 5), 10 | feet((byte) 6), 11 | lhand((byte) 7), 12 | rhand((byte) 8), 13 | lrhand((byte) 9), 14 | rfinger((byte) 10), 15 | lfinger((byte) 11), 16 | lear((byte) 12), 17 | rear((byte) 13), 18 | neck((byte) 14), 19 | underwear((byte) 15), 20 | ring((byte) 16), 21 | earring((byte) 17); 22 | 23 | private final byte value; 24 | 25 | ItemSlot(byte value) { 26 | this.value = value; 27 | } 28 | 29 | public byte getValue() { 30 | return value; 31 | } 32 | 33 | public static ItemSlot getSlot(int value) { 34 | for (ItemSlot slot : ItemSlot.values()) { 35 | if (slot.getValue() == value) { 36 | return slot; 37 | } 38 | } 39 | return null; 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/Material.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum Material { 4 | crystal((byte) 0), 5 | steel((byte) 1), 6 | fine_steel((byte) 2), 7 | blood_steel((byte) 3), 8 | bronze((byte) 4), 9 | silver((byte) 5), 10 | gold((byte) 6), 11 | mithril((byte) 7), 12 | oriharukon((byte) 8), 13 | paper((byte) 9), 14 | wood((byte) 10), 15 | cloth((byte) 11), 16 | leather((byte) 12), 17 | bone((byte) 13), 18 | horn((byte) 14), 19 | damascus((byte) 15), 20 | adamantite((byte) 16), 21 | chrysolite((byte) 17), 22 | liquid((byte) 18), 23 | scale_of_dragon((byte) 19), 24 | dyestuff((byte) 20), 25 | cobweb((byte) 21), 26 | seed((byte) 22), 27 | cotton((byte) 23); 28 | 29 | private final byte value; 30 | 31 | Material(byte value) { 32 | this.value = value; 33 | } 34 | 35 | public byte getValue() { 36 | return value; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/item/WeaponType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.item; 2 | 3 | public enum WeaponType { 4 | none((byte) 0), 5 | sword((byte) 1), 6 | blunt((byte) 2), 7 | dagger((byte) 3), 8 | bow((byte) 4), 9 | pole((byte) 5), 10 | etc((byte) 6), 11 | fist((byte) 7), 12 | dual((byte) 8), 13 | dualfist((byte) 9), 14 | bigsword((byte) 10), 15 | pet((byte) 11), 16 | rod((byte) 12), 17 | bigblunt((byte) 13); 18 | 19 | private final byte value; 20 | 21 | WeaponType(byte value) { 22 | this.value = value; 23 | } 24 | 25 | public byte getValue() { 26 | return value; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/network/GameClientState.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.network; 2 | 3 | public enum GameClientState { 4 | /** Client has just connected . */ 5 | CONNECTED, 6 | /** Client has authed but doesn't have character attached to it yet. */ 7 | AUTHED, 8 | /** Client has selected a character, but it hasn't joined the server yet. */ 9 | JOINING, 10 | /** Client has selected a char and is in game. */ 11 | IN_GAME 12 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/network/packettypes/external/ClientPacketType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.network.packettypes.external; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public enum ClientPacketType { 7 | Ping((byte)0x00), 8 | ProtocolVersion((byte)0x01), 9 | AuthLogin((byte)0x02), 10 | SendMessage((byte)0x03), 11 | RequestMove((byte)0x04), 12 | LoadWorld((byte)0x05), 13 | RequestRotate((byte)0x06), 14 | RequestAnim((byte)0x07), 15 | RequestAttack((byte)0x08), 16 | RequestMoveDirection((byte)0x09), 17 | RequestSetTarget((byte)0x0A), 18 | RequestAutoAttack((byte)0x0B), 19 | CharSelect((byte) 0x0C), 20 | RequestInventoryOpen((byte) 0x0D), 21 | RequestInventoryUpdateOrder((byte) 0x0E), 22 | UseItem((byte) 0x0F), 23 | RequestUnEquipItem((byte) 0x10), 24 | RequestDestroyItem((byte) 0x11), 25 | RequestDropItem((byte) 0x12), 26 | RequestDisconnect((byte) 0x13), 27 | RequestRestart((byte) 0x14), 28 | RequestShortcutReg((byte) 0x15), 29 | RequestShortcutDel((byte) 0x16), 30 | RequestActionUse((byte) 0x17); 31 | 32 | private final byte value; 33 | 34 | ClientPacketType(byte value) { 35 | this.value = value; 36 | } 37 | 38 | public byte getValue() { 39 | return value; 40 | } 41 | 42 | private static final Map BY_VALUE = new HashMap<>(); 43 | 44 | static { 45 | for (ClientPacketType type : values()) { 46 | BY_VALUE.put(type.getValue(), type); 47 | } 48 | } 49 | 50 | public static ClientPacketType fromByte(byte value) { 51 | ClientPacketType result = BY_VALUE.get(value); 52 | if (result == null) { 53 | throw new IllegalArgumentException("Invalid byte value for ClientPacketType: " + value); 54 | } 55 | return result; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/network/packettypes/external/ServerPacketType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.network.packettypes.external; 2 | 3 | import lombok.Getter; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | @Getter 9 | public enum ServerPacketType { 10 | Ping((byte)0x00), 11 | Key((byte)0x01), 12 | LoginFail((byte)0x02), 13 | CharSelectionInfo((byte)0x03), 14 | MessagePacket((byte)0x04), 15 | SystemMessage((byte)0x05), 16 | PlayerInfo((byte)0x06), 17 | ObjectPosition((byte)0x07), 18 | RemoveObject((byte)0x08), 19 | ObjectRotation((byte)0x09), 20 | ObjectAnimation((byte)0x0A), 21 | ApplyDamage((byte)0x0B), 22 | NpcInfo((byte)0x0C), 23 | ObjectMoveTo((byte)0x0D), 24 | UserInfo((byte)0x0E), 25 | ObjectMoveDirection((byte)0x0F), 26 | GameTimePacket((byte)0x10), 27 | EntitySetTarget((byte)0x11), 28 | AutoAttackStart((byte)0x12), 29 | AutoAttackStop((byte)0x13), 30 | ActionFailed((byte)0x14), 31 | ServerClose((byte)0x15), 32 | StatusUpdate((byte)0x16), 33 | ActionAllowed((byte)0x17), 34 | InventoryItemList((byte)0x18), 35 | InventoryUpdate((byte)0x19), 36 | LeaveWorld((byte)0x1A), 37 | RestartResponse((byte)0x1B), 38 | ShortcutInit((byte)0x1C), 39 | ShortcutRegister((byte)0x1D), 40 | SocialAction((byte)0x1E), 41 | ChangeWaitType((byte)0x1F), 42 | ChangeMoveType((byte)0x20); 43 | 44 | private final byte value; 45 | 46 | ServerPacketType(byte value) { 47 | this.value = value; 48 | } 49 | 50 | private static final Map BY_VALUE = new HashMap<>(); 51 | 52 | static { 53 | for (ServerPacketType type : values()) { 54 | BY_VALUE.put(type.getValue(), type); 55 | } 56 | } 57 | 58 | public static ServerPacketType fromByte(byte value) { 59 | ServerPacketType result = BY_VALUE.get(value); 60 | if (result == null) { 61 | throw new IllegalArgumentException("Invalid byte value for ClientPacketType: " + value); 62 | } 63 | return result; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/network/packettypes/internal/GameServerPacketType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.network.packettypes.internal; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public enum GameServerPacketType { 7 | BlowFishKey((byte) 0), 8 | AuthRequest((byte) 1), 9 | ServerStatus((byte) 2), 10 | PlayerInGame((byte) 3), 11 | PlayerLogout((byte) 4), 12 | ReplyCharacters((byte) 5), 13 | PlayerAuthRequest((byte) 6); 14 | 15 | private final byte value; 16 | 17 | GameServerPacketType(byte value) { 18 | this.value = value; 19 | } 20 | 21 | public byte getValue() { 22 | return value; 23 | } 24 | 25 | private static final Map BY_VALUE = new HashMap<>(); 26 | 27 | static { 28 | for (GameServerPacketType type : values()) { 29 | BY_VALUE.put(type.getValue(), type); 30 | } 31 | } 32 | 33 | public static GameServerPacketType fromByte(byte value) { 34 | GameServerPacketType result = BY_VALUE.get(value); 35 | if (result == null) { 36 | throw new IllegalArgumentException("Invalid byte value for ClientPacketType: " + value); 37 | } 38 | return result; 39 | } 40 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/enums/network/packettypes/internal/LoginServerPacketType.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.enums.network.packettypes.internal; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public enum LoginServerPacketType { 7 | InitLS((byte)0), 8 | Fail((byte)1), 9 | AuthResponse((byte) 2), 10 | RequestCharacters((byte) 4), 11 | PlayerAuthResponse((byte)5), 12 | KickPlayer((byte) 6); 13 | 14 | private final byte value; 15 | 16 | LoginServerPacketType(byte value) { 17 | this.value = value; 18 | } 19 | 20 | public byte getValue() { 21 | return value; 22 | } 23 | 24 | private static final Map BY_VALUE = new HashMap<>(); 25 | 26 | static { 27 | for (LoginServerPacketType type : values()) { 28 | BY_VALUE.put(type.getValue(), type); 29 | } 30 | } 31 | 32 | public static LoginServerPacketType fromByte(byte value) { 33 | LoginServerPacketType result = BY_VALUE.get(value); 34 | if (result == null) { 35 | throw new IllegalArgumentException("Invalid byte value for ClientPacketType: " + value); 36 | } 37 | return result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/CharSelectInfoPackage.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model; 2 | 3 | import com.shnok.javaserver.db.entity.DBPlayerItem; 4 | import com.shnok.javaserver.db.repository.PlayerItemRepository; 5 | import com.shnok.javaserver.enums.item.ItemSlot; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | import java.util.List; 10 | 11 | @Getter 12 | @Setter 13 | public class CharSelectInfoPackage { 14 | private String name; 15 | private int objectId = 0; 16 | private int exp = 0; 17 | private int sp = 0; 18 | private int clanId = 0; 19 | private int race = 0; 20 | private int classId = 0; 21 | private long deleteTimer = 0L; 22 | private long lastAccess = 0L; 23 | private int face = 0; 24 | private int hairStyle = 0; 25 | private int hairColor = 0; 26 | private int sex = 0; 27 | private int level = 1; 28 | private int maxCp = 0; 29 | private int currentCp = 0; 30 | private int maxHp = 0; 31 | private int currentHp = 0; 32 | private int maxMp = 0; 33 | private int currentMp = 0; 34 | private final int[] paperdoll; 35 | private int karma = 0; 36 | private int pkKills = 0; 37 | private int pvpKills = 0; 38 | private float x = 0; 39 | private float y = 0; 40 | private float z = 0; 41 | private int accessLevel = 0; 42 | 43 | public CharSelectInfoPackage(int objectId, String name) { 44 | setObjectId(objectId); 45 | setName(name); 46 | 47 | paperdoll = new int[31]; 48 | 49 | List equippedItems = PlayerItemRepository.getInstance().getEquippedItemsForUser(objectId); 50 | equippedItems.forEach((item) -> { 51 | paperdoll[item.getSlot()] = item.getItemId(); 52 | }); 53 | } 54 | 55 | public int getPaperdollItemId(byte slot) { 56 | return paperdoll[slot]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/Hit.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model; 2 | 3 | import com.shnok.javaserver.model.object.GameObject; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | public class Hit { 8 | private static final int HITFLAG_USESS = 0x10; 9 | private static final int HITFLAG_CRIT = 0x20; 10 | private static final int HITFLAG_SHLD = 0x40; 11 | private static final int HITFLAG_MISS = 0x80; 12 | 13 | private final int targetId; 14 | private final int damage; 15 | private int flags = 0; 16 | 17 | public Hit(GameObject target, int damage, boolean miss, boolean crit, byte shld, boolean soulshot, int ssGrade) { 18 | targetId = target.getId(); 19 | this.damage = damage; 20 | 21 | if (soulshot) { 22 | flags |= HITFLAG_USESS | ssGrade; 23 | } 24 | 25 | if (crit) { 26 | flags |= HITFLAG_CRIT; 27 | } 28 | 29 | if (shld > 0) { 30 | flags |= HITFLAG_SHLD; 31 | } 32 | 33 | if (miss) { 34 | flags |= HITFLAG_MISS; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/Party.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model; 2 | 3 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 4 | import lombok.Getter; 5 | 6 | import java.util.List; 7 | 8 | @Getter 9 | public class Party { 10 | private List members; 11 | } 12 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/PlayerAppearance.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class PlayerAppearance { 9 | private byte face; 10 | private byte hairColor; 11 | private byte hairStyle; 12 | private boolean sex; // Female true(1) 13 | private boolean invisible = false; 14 | 15 | public PlayerAppearance(byte face, byte hairColor, byte hairStyle, boolean sex) { 16 | this.face = face; 17 | this.hairColor = hairColor; 18 | this.hairStyle = hairStyle; 19 | this.sex = sex; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/conditions/ConditionListener.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.conditions; 2 | 3 | /** 4 | * The listener interface for receiving condition events.
5 | * The class that is interested in processing a condition event implements this interface,
6 | * and the object created with that class is registered with a component using the component's
7 | * addConditionListener method.
8 | * When the condition event occurs, that object's appropriate method is invoked. 9 | * @author mkizub 10 | */ 11 | public interface ConditionListener { 12 | 13 | void notifyChanged(); 14 | } 15 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/item/ItemInfo.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.item; 2 | 3 | import com.shnok.javaserver.db.entity.DBItem; 4 | import com.shnok.javaserver.model.object.ItemInstance; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class ItemInfo { 9 | private int objectId; 10 | private DBItem item; 11 | private int enchant; 12 | private int count; 13 | private int price; 14 | private byte equipped; 15 | private byte category; 16 | private int slot; 17 | 18 | /** 19 | * The action to do clientside (1=ADD, 2=MODIFY, 3=REMOVE) 20 | */ 21 | private int change; 22 | private int time; 23 | private int location; 24 | 25 | public ItemInfo(ItemInstance item) { 26 | if (item == null) { 27 | return; 28 | } 29 | 30 | // Get the Identifier of the L2ItemInstance 31 | objectId = item.getId(); 32 | 33 | // Get the L2Item of the L2ItemInstance 34 | this.item = item.getItem(); 35 | 36 | // Get the enchant level of the L2ItemInstance 37 | enchant = item.getEnchantLevel(); 38 | 39 | // Get the quantity of the L2ItemInstance 40 | count = item.getCount(); 41 | 42 | // Verify if the L2ItemInstance is equipped 43 | equipped = item.isEquipped() ? (byte) 1 : (byte) 0; 44 | 45 | // Get the action to do clientside 46 | switch (item.getLastChange()) { 47 | case (ItemInstance.ADDED): 48 | change = 1; 49 | break; 50 | case (ItemInstance.MODIFIED): 51 | change = 2; 52 | break; 53 | case (ItemInstance.REMOVED): 54 | change = 3; 55 | break; 56 | } 57 | 58 | // Get shadow item mana 59 | location = item.getLocation().getValue(); 60 | category = item.getItemCategory().getValue(); 61 | time = item.getItem().getDuration(); 62 | slot = item.getSlot(); 63 | } 64 | 65 | public ItemInfo(ItemInstance item, int change) { 66 | this(item); 67 | this.change = change; 68 | } 69 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/item/listeners/GearListener.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.item.listeners; 2 | 3 | import com.shnok.javaserver.model.object.ItemInstance; 4 | 5 | public interface GearListener { 6 | public void notifyEquipped(int slot, ItemInstance inst); 7 | 8 | public void notifyUnequipped(int slot, ItemInstance inst); 9 | } 10 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/item/listeners/StatsListener.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.item.listeners; 2 | 3 | import com.shnok.javaserver.model.object.ItemInstance; 4 | import com.shnok.javaserver.model.object.entity.Entity; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class StatsListener implements GearListener { 9 | private final Entity owner; 10 | 11 | public StatsListener(Entity owner) { 12 | this.owner = owner; 13 | } 14 | 15 | @Override 16 | public void notifyUnequipped(int slot, ItemInstance item) { 17 | getOwner().removeStatsOwner(item); 18 | } 19 | 20 | @Override 21 | public void notifyEquipped(int slot, ItemInstance item) { 22 | getOwner().addStatFuncs(item.getStatFuncs()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/network/SessionKey.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.network; 2 | 3 | public class SessionKey { 4 | public int playOkID1; 5 | public int playOkID2; 6 | public int loginOkID1; 7 | public int loginOkID2; 8 | 9 | /** 10 | * Instantiates a new session key. 11 | * 12 | * @param loginOK1 the login o k1 13 | * @param loginOK2 the login o k2 14 | * @param playOK1 the play o k1 15 | * @param playOK2 the play o k2 16 | */ 17 | public SessionKey(int loginOK1, int loginOK2, int playOK1, int playOK2) { 18 | playOkID1 = playOK1; 19 | playOkID2 = playOK2; 20 | loginOkID1 = loginOK1; 21 | loginOkID2 = loginOK2; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "PlayOk: " + playOkID1 + " " + playOkID2 + " LoginOk:" + loginOkID1 + " " + loginOkID2; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/network/WaitingClient.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.network; 2 | 3 | import com.shnok.javaserver.thread.GameClientThread; 4 | 5 | public class WaitingClient { 6 | public String account; 7 | public GameClientThread gameClient; 8 | public SessionKey session; 9 | 10 | /** 11 | * Instantiates a new waiting client. 12 | * @param acc the acc 13 | * @param client the client 14 | * @param key the key 15 | */ 16 | public WaitingClient(String acc, GameClientThread client, SessionKey key) { 17 | account = acc; 18 | gameClient = client; 19 | session = key; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/shortcut/Shortcut.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.shortcut; 2 | 3 | import com.shnok.javaserver.enums.ShortcutType; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | public class Shortcut { 8 | /** 9 | * Slot from 0 to 11. 10 | */ 11 | private final int slot; 12 | /** 13 | * Page from 0 to 9. 14 | */ 15 | private final int page; 16 | /** 17 | * Type: item, skill, action, macro, recipe, bookmark. 18 | */ 19 | private final ShortcutType type; 20 | /** 21 | * Shortcut ID. 22 | */ 23 | private final int id; 24 | /** 25 | * Shortcut level (skills). 26 | */ 27 | private final int level; 28 | /** 29 | * Character type: 1 player, 2 summon. 30 | */ 31 | private final int characterType; 32 | 33 | public Shortcut(int slot, int page, ShortcutType type, int id, int level, int characterType) { 34 | this.slot = slot; 35 | this.page = page; 36 | this.type = type; 37 | this.id = id; 38 | this.level = level; 39 | this.characterType = characterType; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/skills/FormulasLegacy.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.skills; 2 | 3 | public class FormulasLegacy { 4 | private static FormulasLegacy _instance; 5 | public static FormulasLegacy getInstance() { 6 | if(_instance == null) { 7 | _instance = new FormulasLegacy(); 8 | } 9 | return _instance; 10 | } 11 | 12 | // Calculate delay (in milliseconds) before next ATTACK 13 | public final int calcPAtkSpd(float atkSpeed) { 14 | // Source L2J 15 | // measured Oct 2006 by Tank6585, formula by Sami 16 | // attack speed 312 equals 1500 ms delay... (or 300 + 40 ms delay?) 17 | if (atkSpeed < 2) { 18 | return 2700; 19 | } 20 | return (int) (470000 / atkSpeed); 21 | } 22 | 23 | // Calculate delay (in milliseconds) for skills cast 24 | // public final int calcMAtkSpd(Skill skill, float skillTime) { 25 | // if (skill.isMagic()) { 26 | // return (int) ((skillTime * 333) / attacker.getMAtkSpd()); 27 | // } 28 | // return (int) ((skillTime * 333) / attacker.getPAtkSpd()); 29 | // } 30 | } 31 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/skills/Skill.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.skills; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class Skill { 9 | private String name; 10 | private float lvlBonusRate; 11 | private int magicLevel; 12 | private float castRange; 13 | private boolean toggle; 14 | } 15 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/Condition.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions; 2 | 3 | public class Condition { 4 | } 5 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMAtkAccuracy.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Stats; 6 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 7 | 8 | public class FuncMAtkAccuracy extends AbstractFunction { 9 | /* 10 | @Override 11 | public double calc(Creature creature, OptionalDouble base, Stat stat) 12 | { 13 | throwIfPresent(base); 14 | 15 | double baseValue = calcWeaponPlusBaseValue(creature, stat); 16 | if (creature.isPlayer()) 17 | { 18 | // Enchanted gloves bonus 19 | baseValue += calcEnchantBodyPart(creature, ItemTemplate.SLOT_GLOVES); 20 | } 21 | return Stat.defaultValue(creature, stat, baseValue + (Math.sqrt(creature.getWIT()) * 3) + (creature.getLevel() * 2)); 22 | } 23 | 24 | */ 25 | private static final FuncMAtkAccuracy _faa_instance = new FuncMAtkAccuracy(); 26 | 27 | public static AbstractFunction getInstance() { 28 | return _faa_instance; 29 | } 30 | 31 | private FuncMAtkAccuracy() { 32 | super(Stats.MAGIC_ACCURACY_COMBAT, 0x10, null, 0, null); 33 | } 34 | 35 | @Override 36 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 37 | final int level = effector.getLevel(); 38 | // [Square(DEX)] * 6 + lvl + weapon hitbonus; 39 | float value = (float) (initVal + (Math.sqrt(effector.getWIT()) * 3) + (level * 2)); 40 | // weapon accuracy ? 41 | return value; 42 | } 43 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMAtkCritical.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncMAtkCritical extends AbstractFunction { 10 | private static final FuncMAtkCritical _fac_instance = new FuncMAtkCritical(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fac_instance; 14 | } 15 | 16 | private FuncMAtkCritical() { 17 | super(Stats.MCRITICAL_RATE, 0x10, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | // CT2: The magic critical rate has been increased to 10 times. 23 | if (!effector.isPlayer() || (effector.getActiveWeaponItem() != null)) { 24 | return initVal * Formulas.WITbonus[effector.getWIT()] * 10; 25 | } 26 | return initVal; 27 | } 28 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMAtkMod.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncMAtkMod extends AbstractFunction { 10 | private static final FuncMAtkMod _fma_instance = new FuncMAtkMod(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fma_instance; 14 | } 15 | 16 | private FuncMAtkMod() { 17 | super(Stats.MAGIC_ATTACK, 0x20, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | // Level Modifier^2 * INT Modifier^2 23 | float lvlMod = Formulas.INTbonus[effector.getINT()]; 24 | float intMod = effector.isPlayer() ? effector.getLevelMod() : effector.getLevelMod(); 25 | return (float) (initVal * Math.pow(lvlMod, 2) * Math.pow(intMod, 2)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMAtkSpeed.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncMAtkSpeed extends AbstractFunction { 10 | private static final FuncMAtkSpeed _fas_instance = new FuncMAtkSpeed(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fas_instance; 14 | } 15 | 16 | private FuncMAtkSpeed() { 17 | super(Stats.MAGIC_ATTACK_SPEED, 0x20, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | return initVal * Formulas.WITbonus[effector.getWIT()]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMDefMod.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.enums.item.ItemSlot; 4 | import com.shnok.javaserver.model.object.entity.Entity; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | import com.shnok.javaserver.model.skills.Skill; 7 | import com.shnok.javaserver.model.stats.Formulas; 8 | import com.shnok.javaserver.model.stats.Stats; 9 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 10 | 11 | public class FuncMDefMod extends AbstractFunction { 12 | private static final FuncMDefMod _fmm_instance = new FuncMDefMod(); 13 | 14 | public static AbstractFunction getInstance() { 15 | return _fmm_instance; 16 | } 17 | 18 | private FuncMDefMod() { 19 | super(Stats.MAGIC_DEFENCE, 0x20, null, 0, null); 20 | } 21 | 22 | @Override 23 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 24 | float value = initVal; 25 | if (effector.isPlayer()) { 26 | PlayerInstance p = (PlayerInstance) effector; 27 | if (p.getInventory().isSlotUsed(ItemSlot.lfinger)) { 28 | value -= 5; 29 | } 30 | if (p.getInventory().isSlotUsed(ItemSlot.rfinger)) { 31 | value -= 5; 32 | } 33 | if (p.getInventory().isSlotUsed(ItemSlot.lear)) { 34 | value -= 9; 35 | } 36 | if (p.getInventory().isSlotUsed(ItemSlot.rear)) { 37 | value -= 9; 38 | } 39 | if (p.getInventory().isSlotUsed(ItemSlot.neck)) { 40 | value -= 13; 41 | } 42 | } 43 | 44 | // if(getStat() == Stats.MAGIC_DEFENCE) 45 | // System.out.println("FuncMdefMod" + " - " + getStat() + " - InitVal:" + initVal + " - GetValue:" + getValue() + " - Calculated:" + 46 | // value * Formulas.MENbonus[effector.getMEN()] * effector.getLevelMod()); 47 | 48 | return value * Formulas.MENbonus[effector.getMEN()] * effector.getLevelMod(); 49 | } 50 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMaxCpMul.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncMaxCpMul extends AbstractFunction { 10 | private static final FuncMaxCpMul _fmcm_instance = new FuncMaxCpMul(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fmcm_instance; 14 | } 15 | 16 | private FuncMaxCpMul() { 17 | super(Stats.MAX_CP, 0x10, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | return initVal * Formulas.CONbonus[effector.getCON()]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMaxHpMul.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncMaxHpMul extends AbstractFunction { 10 | private static final FuncMaxHpMul _fmhm_instance = new FuncMaxHpMul(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fmhm_instance; 14 | } 15 | 16 | private FuncMaxHpMul() { 17 | super(Stats.MAX_HP, 0x10, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | return initVal * Formulas.CONbonus[effector.getCON()]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMaxMpMul.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncMaxMpMul extends AbstractFunction { 10 | private static final FuncMaxMpMul _fmmm_instance = new FuncMaxMpMul(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fmmm_instance; 14 | } 15 | 16 | private FuncMaxMpMul() { 17 | super(Stats.MAX_MP, 0x10, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | return initVal * Formulas.MENbonus[effector.getMEN()]; 23 | } 24 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncMoveSpeed.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncMoveSpeed extends AbstractFunction { 10 | private static final FuncMoveSpeed _fms_instance = new FuncMoveSpeed(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fms_instance; 14 | } 15 | 16 | private FuncMoveSpeed() { 17 | super(Stats.MOVE_SPEED, 0x30, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | return initVal * Formulas.DEXbonus[effector.getDEX()]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncPAtkAccuracy.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Stats; 6 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 7 | 8 | public class FuncPAtkAccuracy extends AbstractFunction { 9 | private static final FuncPAtkAccuracy _faa_instance = new FuncPAtkAccuracy(); 10 | 11 | public static AbstractFunction getInstance() { 12 | return _faa_instance; 13 | } 14 | 15 | private FuncPAtkAccuracy() { 16 | super(Stats.POWER_ACCURACY_COMBAT, 0x10, null, 0, null); 17 | } 18 | 19 | @Override 20 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 21 | final int level = effector.getLevel(); 22 | // [Square(DEX)] * 6 + lvl + weapon hitbonus; 23 | float value = (float) (initVal + (Math.sqrt(effector.getDEX()) * 6) + level); 24 | if (level > 77) { 25 | value += level - 76; 26 | } 27 | if (level > 69) { 28 | value += level - 69; 29 | } 30 | return value; 31 | } 32 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncPAtkCritical.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncPAtkCritical extends AbstractFunction { 10 | private static final FuncPAtkCritical _fac_instance = new FuncPAtkCritical(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fac_instance; 14 | } 15 | 16 | private FuncPAtkCritical() { 17 | super(Stats.CRITICAL_RATE, 0x30, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | // System.out.println("FuncPAtkCritical INIT VAL: " + initVal); 23 | // System.out.println("FuncPAtkCritical getValue: " + getValue()); 24 | // System.out.println("FuncPAtkCritical VAL BONUS MULTIPLIER: " + Formulas.DEXbonus[effector.getDEX()]); 25 | 26 | if ((effector.isPlayer()) && (effector.getActiveWeaponInstance() == null)) { 27 | return initVal; 28 | } 29 | 30 | return initVal * Formulas.DEXbonus[effector.getDEX()] * 10; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncPAtkEvasion.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Stats; 6 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 7 | 8 | public class FuncPAtkEvasion extends AbstractFunction { 9 | private static final FuncPAtkEvasion _fae_instance = new FuncPAtkEvasion(); 10 | 11 | public static AbstractFunction getInstance() { 12 | return _fae_instance; 13 | } 14 | 15 | private FuncPAtkEvasion() { 16 | super(Stats.POWER_EVASION_RATE, 0x10, null, 0, null); 17 | } 18 | 19 | @Override 20 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 21 | final int level = effector.getLevel(); 22 | float value = initVal; 23 | if (effector.isPlayer()) { 24 | // [Square(DEX)] * 6 + lvl; 25 | value += (Math.sqrt(effector.getDEX()) * 6) + level; 26 | float diff = level - 69; 27 | if (level >= 78) { 28 | diff *= 1.2; 29 | } 30 | if (level >= 70) { 31 | value += diff; 32 | } 33 | } else { 34 | // [Square(DEX)] * 6 + lvl; 35 | value += (Math.sqrt(effector.getDEX()) * 6) + level; 36 | if (level > 69) { 37 | value += (level - 69) + 2; 38 | } 39 | } 40 | return (int) value; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncPAtkMod.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncPAtkMod extends AbstractFunction { 10 | private static final FuncPAtkMod _fpa_instance = new FuncPAtkMod(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fpa_instance; 14 | } 15 | 16 | private FuncPAtkMod() { 17 | super(Stats.POWER_ATTACK, 0x30, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | return initVal * Formulas.STRbonus[effector.getSTR()] * effector.getLevelMod(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncPAtkSpeed.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Formulas; 6 | import com.shnok.javaserver.model.stats.Stats; 7 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 8 | 9 | public class FuncPAtkSpeed extends AbstractFunction { 10 | private static final FuncPAtkSpeed _fas_instance = new FuncPAtkSpeed(); 11 | 12 | public static AbstractFunction getInstance() { 13 | return _fas_instance; 14 | } 15 | 16 | private FuncPAtkSpeed() { 17 | super(Stats.POWER_ATTACK_SPEED, 0x20, null, 0, null); 18 | } 19 | 20 | @Override 21 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 22 | return initVal * Formulas.DEXbonus[effector.getDEX()]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/fomulas/FuncPDefMod.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.fomulas; 2 | 3 | import com.shnok.javaserver.enums.item.ItemSlot; 4 | import com.shnok.javaserver.model.object.entity.Entity; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | import com.shnok.javaserver.model.skills.Skill; 7 | import com.shnok.javaserver.model.stats.Formulas; 8 | import com.shnok.javaserver.model.stats.Stats; 9 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 10 | 11 | public class FuncPDefMod extends AbstractFunction { 12 | private static final FuncPDefMod _fmm_instance = new FuncPDefMod(); 13 | 14 | public static AbstractFunction getInstance() { 15 | return _fmm_instance; 16 | } 17 | 18 | private FuncPDefMod() { 19 | super(Stats.POWER_DEFENCE, 0x20, null, 0, null); 20 | } 21 | 22 | @Override 23 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 24 | float value = initVal; 25 | if (effector.isPlayer()) { 26 | final PlayerInstance p = (PlayerInstance) effector; 27 | if (p.getInventory().isSlotUsed(ItemSlot.head)) { 28 | value -= 12; 29 | } 30 | if (p.getInventory().isSlotUsed(ItemSlot.chest)) { 31 | value -= ((p.getTemplate().getClassId().isMage()) ? 15 : 31); 32 | } 33 | if (p.getInventory().isSlotUsed(ItemSlot.legs)) { 34 | value -= ((p.getTemplate().getClassId().isMage()) ? 8 : 18); 35 | } 36 | if (p.getInventory().isSlotUsed(ItemSlot.gloves)) { 37 | value -= 8; 38 | } 39 | if (p.getInventory().isSlotUsed(ItemSlot.feet)) { 40 | value -= 7; 41 | } 42 | } 43 | 44 | // if(getStat() == Stats.POWER_DEFENCE) 45 | // System.out.println("FuncPdefMod" + " - " + getStat() + " - InitVal:" + initVal + " - GetValue:" + getValue() + " - Calculated:" + 46 | // value * effector.getLevelMod()); 47 | 48 | return value * effector.getLevelMod(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/items/FuncItemStatAdd.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.items; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Stats; 6 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 7 | import com.shnok.javaserver.model.stats.functions.Condition; 8 | 9 | public class FuncItemStatAdd extends AbstractFunction { 10 | /** 11 | * Constructor of Func. 12 | * 13 | * @param stat the stat 14 | * @param order the order 15 | * @param owner the owner 16 | * @param value the value 17 | * @param applyCond the apply condition 18 | */ 19 | public FuncItemStatAdd(Stats stat, int order, Object owner, float value, Condition applyCond) { 20 | super(stat, order, owner, value, applyCond); 21 | } 22 | 23 | @Override 24 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 25 | // if(getStat() == Stats.POWER_DEFENCE) 26 | // System.out.println("FuncItemStatAdd" + " - " + getStat() + " - InitVal:" + initVal + " - GetValue:" + getValue() + " - Calculated:" + initVal + getValue()); 27 | return initVal + getValue(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/stats/functions/items/FuncItemStatSet.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.stats.functions.items; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.skills.Skill; 5 | import com.shnok.javaserver.model.stats.Stats; 6 | import com.shnok.javaserver.model.stats.functions.AbstractFunction; 7 | import com.shnok.javaserver.model.stats.functions.Condition; 8 | 9 | public class FuncItemStatSet extends AbstractFunction { 10 | /** 11 | * Constructor of Func. 12 | * 13 | * @param stat the stat 14 | * @param order the order 15 | * @param owner the owner 16 | * @param value the value 17 | * @param applyCond the apply condition 18 | */ 19 | public FuncItemStatSet(Stats stat, int order, Object owner, float value, Condition applyCond) { 20 | super(stat, order, owner, value, applyCond); 21 | } 22 | 23 | @Override 24 | public float calc(Entity effector, Entity effected, Skill skill, float initVal) { 25 | // if(getStat() == Stats.CRITICAL_RATE) { 26 | // System.out.println("FuncItemStatSet INIT VAL: " + initVal); 27 | // System.out.println("FuncItemStatSet getValue: " + getValue()); 28 | // } 29 | 30 | return getValue(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/status/NpcStatus.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.status; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import com.shnok.javaserver.model.object.entity.NpcInstance; 5 | import com.shnok.javaserver.model.object.entity.PlayerInstance; 6 | import lombok.ToString; 7 | 8 | @ToString 9 | public class NpcStatus extends Status { 10 | public NpcStatus(NpcInstance activeChar) { 11 | super(activeChar); 12 | } 13 | 14 | @Override 15 | public void reduceHp(float value, Entity attacker) { 16 | reduceHp(value, attacker, true, false, false); 17 | } 18 | 19 | @Override 20 | public void reduceHp(float value, Entity attacker, boolean awake, boolean isDOT, boolean isHpConsumption) { 21 | if (getOwner().isDead()) { 22 | return; 23 | } 24 | 25 | if (attacker != null) { 26 | final PlayerInstance attackerPlayer = (PlayerInstance) attacker; 27 | // if (attackerPlayer.isInDuel()) { 28 | // attackerPlayer.setDuelState(DuelState.INTERRUPTED); 29 | // } 30 | 31 | // Add attackers to npc's attacker list 32 | ((NpcInstance)getOwner()).addAttackerToAttackByList(attacker); 33 | } 34 | 35 | super.reduceHp(value, attacker, awake, isDOT, isHpConsumption); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/model/template/EntityTemplate.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.model.template; 2 | 3 | import com.shnok.javaserver.enums.MoveType; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class EntityTemplate { 8 | public int baseSTR; 9 | public int baseCON; 10 | public int baseDEX; 11 | public int baseINT; 12 | public int baseWIT; 13 | public int baseMEN; 14 | public int baseHpMax; 15 | public int baseCpMax; 16 | public int baseMpMax; 17 | public float baseHpReg; 18 | public float baseMpReg; 19 | public float baseCpReg; 20 | public int basePAtk; 21 | public int baseMAtk; 22 | public int basePDef; 23 | public int baseMDef; 24 | public int basePAtkSpd; 25 | public int baseMAtkSpd; 26 | public float baseMReuseRate; 27 | public float baseAtkRange; 28 | public int baseCritRate; 29 | public int baseWalkSpd; 30 | public int baseRunSpd; 31 | public float collisionRadius; 32 | public float collisionHeight; 33 | 34 | public EntityTemplate() {} 35 | 36 | public int getBaseMoveSpeed(MoveType moveType) { 37 | if(moveType == MoveType.RUN) { 38 | return baseRunSpd; 39 | } 40 | 41 | return baseWalkSpd; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/pathfinding/MoveData.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.pathfinding; 2 | 3 | import com.shnok.javaserver.model.Point3D; 4 | 5 | import java.util.List; 6 | 7 | public class MoveData { 8 | public long moveTimestamp; 9 | public Point3D startPosition; 10 | public Point3D destination; 11 | public long moveStartTime; 12 | public int ticksToMove; 13 | public float xSpeedTicks; 14 | public float ySpeedTicks; 15 | public float zSpeedTicks; 16 | public List path; 17 | } 18 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/pathfinding/node/FastNodeList.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.pathfinding.node; 2 | 3 | public class FastNodeList { 4 | private final Node[] _list; 5 | private int _size; 6 | 7 | public FastNodeList(int size) { 8 | _list = new Node[size]; 9 | } 10 | 11 | public void add(Node n) { 12 | _list[_size] = n; 13 | _size++; 14 | } 15 | 16 | public boolean contains(Node n) { 17 | for (int i = 0; i < _size; i++) { 18 | if (_list[i].equals(n)) { 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | 25 | public boolean containsRev(Node n) { 26 | for (int i = _size - 1; i >= 0; i--) { 27 | if (_list[i].equals(n)) { 28 | return true; 29 | } 30 | } 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/pathfinding/node/Node.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.pathfinding.node; 2 | 3 | import com.shnok.javaserver.model.Point3D; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class Node implements Comparable { 8 | private Point3D nodeIndex; 9 | private Point3D worldPosition; 10 | private Point3D center; 11 | private float nodeSize; 12 | private float cost; 13 | private Node parentNode; 14 | 15 | public Node(Point3D nodeIndex, Point3D worldPosition, float nodeSize) { 16 | this.nodeIndex = nodeIndex; 17 | this.worldPosition = worldPosition; 18 | this.nodeSize = nodeSize; 19 | this.center = new Point3D ( 20 | worldPosition.getX() + nodeSize / 2f, 21 | worldPosition.getY(), 22 | worldPosition.getZ() + nodeSize / 2f); 23 | } 24 | 25 | public Node(Node original) { 26 | nodeIndex = original.nodeIndex; 27 | worldPosition = original.worldPosition; 28 | nodeSize = original.nodeSize; 29 | center = original.center; 30 | } 31 | 32 | @Override 33 | public int hashCode() { 34 | return worldPosition.hashCode(); 35 | } 36 | 37 | @Override 38 | public boolean equals(Object arg0) { 39 | if (!(arg0 instanceof Node)) { 40 | return false; 41 | } 42 | Node n = (Node) arg0; 43 | // Check if x,y,z are the same 44 | return (worldPosition.getX() == n.getWorldPosition().getX()) && 45 | (worldPosition.getY() == n.getWorldPosition().getY()) && 46 | (worldPosition.getZ() == n.getWorldPosition().getZ()); 47 | } 48 | 49 | @Override 50 | public int compareTo(Node o) { 51 | return Float.compare(o.nodeIndex.getY(), this.nodeIndex.getY()); 52 | } 53 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/security/BlowFishKeygen.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.security; 2 | 3 | /** 4 | * Blowfish keygen for GameServer client connections. 5 | */ 6 | public class BlowFishKeygen { 7 | private static final int CRYPT_KEYS_SIZE = 20; 8 | private static final byte[][] CRYPT_KEYS = new byte[CRYPT_KEYS_SIZE][16]; 9 | 10 | static { 11 | // init the GS encryption keys on class load 12 | 13 | for (int i = 0; i < CRYPT_KEYS_SIZE; i++) { 14 | // randomize the 8 first bytes 15 | for (int j = 0; j < CRYPT_KEYS[i].length; j++) { 16 | CRYPT_KEYS[i][j] = (byte) Rnd.get(255); 17 | } 18 | 19 | // the last 8 bytes are static 20 | CRYPT_KEYS[i][8] = (byte) 0xc8; 21 | CRYPT_KEYS[i][9] = (byte) 0x27; 22 | CRYPT_KEYS[i][10] = (byte) 0x93; 23 | CRYPT_KEYS[i][11] = (byte) 0x01; 24 | CRYPT_KEYS[i][12] = (byte) 0xa1; 25 | CRYPT_KEYS[i][13] = (byte) 0x6c; 26 | CRYPT_KEYS[i][14] = (byte) 0x31; 27 | CRYPT_KEYS[i][15] = (byte) 0x97; 28 | } 29 | } 30 | 31 | // block instantiation 32 | private BlowFishKeygen() { 33 | 34 | } 35 | 36 | /** 37 | * Returns a key from this keygen pool, the logical ownership is retained by this keygen.
38 | * Thus when getting a key with interests other then read-only a copy must be performed.
39 | * @return A key from this keygen pool. 40 | */ 41 | public static byte[] getRandomKey() { 42 | return CRYPT_KEYS[Rnd.get(CRYPT_KEYS_SIZE)]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/security/GameCrypt.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.security; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public class GameCrypt { 7 | private final byte[] _inKey = new byte[16]; 8 | private final byte[] _outKey = new byte[16]; 9 | 10 | public void setKey(byte[] key) { 11 | System.arraycopy(key, 0, _inKey, 0, 16); 12 | System.arraycopy(key, 0, _outKey, 0, 16); 13 | } 14 | 15 | public void decrypt(byte[] raw, final int offset, final int size) { 16 | int temp = 0; 17 | for (int i = 0; i < size; i++) { 18 | int temp2 = raw[offset + i] & 0xFF; 19 | raw[offset + i] = (byte) (temp2 ^ _inKey[i & 15] ^ temp); 20 | temp = temp2; 21 | } 22 | 23 | int old = _inKey[8] & 0xff; 24 | old |= (_inKey[9] << 8) & 0xff00; 25 | old |= (_inKey[10] << 0x10) & 0xff0000; 26 | old |= (_inKey[11] << 0x18) & 0xff000000; 27 | 28 | old += size; 29 | 30 | _inKey[8] = (byte) (old & 0xff); 31 | _inKey[9] = (byte) ((old >> 0x08) & 0xff); 32 | _inKey[10] = (byte) ((old >> 0x10) & 0xff); 33 | _inKey[11] = (byte) ((old >> 0x18) & 0xff); 34 | } 35 | 36 | public void encrypt(byte[] raw, final int offset, final int size) { 37 | 38 | int temp = 0; 39 | for (int i = 0; i < size; i++) { 40 | int temp2 = raw[offset + i] & 0xFF; 41 | temp = temp2 ^ _outKey[i & 15] ^ temp; 42 | raw[offset + i] = (byte) temp; 43 | } 44 | 45 | int old = _outKey[8] & 0xff; 46 | old |= (_outKey[9] << 8) & 0xff00; 47 | old |= (_outKey[10] << 0x10) & 0xff0000; 48 | old |= (_outKey[11] << 0x18) & 0xff000000; 49 | 50 | old += size; 51 | 52 | _outKey[8] = (byte) (old & 0xff); 53 | _outKey[9] = (byte) ((old >> 0x08) & 0xff); 54 | _outKey[10] = (byte) ((old >> 0x10) & 0xff); 55 | _outKey[11] = (byte) ((old >> 0x18) & 0xff); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/security/ScrambledKeyPair.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.security; 2 | 3 | import java.math.BigInteger; 4 | import java.security.KeyPair; 5 | import java.security.interfaces.RSAPublicKey; 6 | 7 | public class ScrambledKeyPair { 8 | 9 | private final KeyPair pair; 10 | 11 | private final byte[] scrambledModulus; 12 | 13 | public ScrambledKeyPair(KeyPair pPair) { 14 | pair = pPair; 15 | scrambledModulus = scrambleModulus(((RSAPublicKey) pair.getPublic()).getModulus()); 16 | } 17 | 18 | public KeyPair getPair() { 19 | return pair; 20 | } 21 | 22 | public byte[] getScrambledModulus() { 23 | return scrambledModulus; 24 | } 25 | 26 | private byte[] scrambleModulus(BigInteger modulus) { 27 | byte[] scrambledMod = modulus.toByteArray(); 28 | 29 | if ((scrambledMod.length == 0x81) && (scrambledMod[0] == 0x00)) { 30 | byte[] temp = new byte[0x80]; 31 | System.arraycopy(scrambledMod, 1, temp, 0, 0x80); 32 | scrambledMod = temp; 33 | } 34 | // step 1 : 0x4d-0x50 <-> 0x00-0x04 35 | for (int i = 0; i < 4; i++) { 36 | byte temp = scrambledMod[i]; 37 | scrambledMod[i] = scrambledMod[0x4d + i]; 38 | scrambledMod[0x4d + i] = temp; 39 | } 40 | // step 2 : xor first 0x40 bytes with last 0x40 bytes 41 | for (int i = 0; i < 0x40; i++) { 42 | scrambledMod[i] = (byte) (scrambledMod[i] ^ scrambledMod[0x40 + i]); 43 | } 44 | // step 3 : xor bytes 0x0d-0x10 with bytes 0x34-0x38 45 | for (int i = 0; i < 4; i++) { 46 | scrambledMod[0x0d + i] = (byte) (scrambledMod[0x0d + i] ^ scrambledMod[0x34 + i]); 47 | } 48 | // step 4 : xor last 0x40 bytes with first 0x40 bytes 49 | for (int i = 0; i < 0x40; i++) { 50 | scrambledMod[0x40 + i] = (byte) (scrambledMod[0x40 + i] ^ scrambledMod[i]); 51 | } 52 | return scrambledMod; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/service/GameServerController.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.service; 2 | 3 | import com.shnok.javaserver.dto.SendablePacket; 4 | import com.shnok.javaserver.enums.network.GameClientState; 5 | import com.shnok.javaserver.thread.GameClientThread; 6 | import lombok.extern.log4j.Log4j2; 7 | 8 | import java.net.Socket; 9 | import java.net.SocketException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | @Log4j2 14 | public class GameServerController { 15 | private static GameServerController instance; 16 | public static GameServerController getInstance() { 17 | if (instance == null) { 18 | instance = new GameServerController(); 19 | } 20 | return instance; 21 | } 22 | 23 | private final List clients = new ArrayList<>(); 24 | 25 | public void addClient(Socket socket) throws SocketException { 26 | GameClientThread client = new GameClientThread(socket); 27 | client.start(); 28 | clients.add(client); 29 | } 30 | 31 | public void removeClient(GameClientThread s) { 32 | synchronized (clients) { 33 | clients.remove(s); 34 | } 35 | } 36 | 37 | public List getAllClients() { 38 | return clients; 39 | } 40 | 41 | // Broadcast to everyone ignoring caller 42 | public void broadcast(SendablePacket packet, GameClientThread current) { 43 | synchronized (clients) { 44 | for (GameClientThread c : clients) { 45 | if (c.getGameClientState() == GameClientState.IN_GAME && c != current) { 46 | c.sendPacket(packet); 47 | } 48 | } 49 | } 50 | } 51 | 52 | // Broadcast to everyone 53 | public void broadcast(SendablePacket packet) { 54 | synchronized (clients) { 55 | for (GameClientThread c : clients) { 56 | if (c.getGameClientState() == GameClientState.IN_GAME) { 57 | c.sendPacket(packet); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/service/GameServerListenerService.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.service; 2 | 3 | import lombok.extern.log4j.Log4j2; 4 | 5 | import java.io.IOException; 6 | import java.net.ServerSocket; 7 | import java.net.Socket; 8 | 9 | import static com.shnok.javaserver.config.Configuration.server; 10 | 11 | @Log4j2 12 | public class GameServerListenerService extends Thread { 13 | private int port; 14 | private ServerSocket serverSocket; 15 | 16 | private static GameServerListenerService instance; 17 | public static GameServerListenerService getInstance() { 18 | if (instance == null) { 19 | instance = new GameServerListenerService(); 20 | } 21 | return instance; 22 | } 23 | 24 | public void Initialize() { 25 | try { 26 | port = server.gameserverPort(); 27 | serverSocket = new ServerSocket(port); 28 | } catch (IOException e) { 29 | throw new RuntimeException("Could not create ServerSocket ", e); 30 | } 31 | } 32 | 33 | @Override 34 | public void run() { 35 | log.info("Server listening on port {}. ", port); 36 | while (true) { 37 | Socket connection = null; 38 | try { 39 | connection = serverSocket.accept(); 40 | GameServerController.getInstance().addClient(connection); 41 | } catch (Exception e) { 42 | e.printStackTrace(); 43 | try { 44 | if (connection != null) { 45 | connection.close(); 46 | } 47 | } catch (Exception e2) { 48 | e2.printStackTrace(); 49 | } 50 | 51 | if (isInterrupted()) { 52 | try { 53 | serverSocket.close(); 54 | } catch (IOException io) { 55 | io.printStackTrace(); 56 | } 57 | break; 58 | } 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/service/ServerShutdownService.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.service; 2 | 3 | import com.shnok.javaserver.thread.GameClientThread; 4 | import lombok.extern.log4j.Log4j2; 5 | 6 | @Log4j2 7 | public class ServerShutdownService extends Thread { 8 | private static ServerShutdownService instance; 9 | public static ServerShutdownService getInstance() { 10 | if (instance == null) { 11 | instance = new ServerShutdownService(); 12 | } 13 | return instance; 14 | } 15 | 16 | 17 | @Override 18 | public void run() { 19 | log.info("Shutting down all threads."); 20 | try { 21 | GameServerListenerService.getInstance().interrupt(); 22 | } catch (Exception e) { 23 | e.printStackTrace(); 24 | } 25 | 26 | try { 27 | for (GameClientThread c : GameServerController.getInstance().getAllClients()) { 28 | c.interrupt(); 29 | } 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } 33 | 34 | try { 35 | ThreadPoolManagerService.getInstance().shutdown(); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | } 39 | 40 | try { 41 | GameTimeControllerService.getInstance().stopTimer(); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/service/factory/IdFactoryService.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.service.factory; 2 | 3 | import com.shnok.javaserver.db.entity.DBCharacter; 4 | import com.shnok.javaserver.db.entity.DBPlayerItem; 5 | import com.shnok.javaserver.db.repository.CharacterRepository; 6 | import com.shnok.javaserver.db.repository.PlayerItemRepository; 7 | import lombok.extern.log4j.Log4j2; 8 | 9 | import java.util.List; 10 | import java.util.concurrent.atomic.AtomicInteger; 11 | 12 | @Log4j2 13 | public abstract class IdFactoryService { 14 | protected boolean initialized; 15 | 16 | private static IdFactoryService instance; 17 | public static IdFactoryService getInstance() { 18 | if (instance == null) { 19 | instance = new BitSetIDFactory(); 20 | } 21 | return instance; 22 | } 23 | 24 | public int[] extractUsedObjectIDs() { 25 | List playerItems = PlayerItemRepository.getInstance().getAllPlayerItems(); 26 | List characters = CharacterRepository.getInstance().getAllCharacters(); 27 | 28 | int[] usedObjectIds = new int[playerItems.size() + characters.size()]; 29 | 30 | AtomicInteger id = new AtomicInteger(); 31 | playerItems.forEach((item) -> { 32 | usedObjectIds[id.getAndIncrement()] = item.getObjectId(); 33 | }); 34 | characters.forEach((character) -> { 35 | usedObjectIds[id.getAndIncrement()] = character.getId(); 36 | }); 37 | 38 | log.debug("[IDFACTORY] Initialized with {} object id(s) already used.", usedObjectIds.length); 39 | return usedObjectIds; 40 | } 41 | 42 | public abstract int getNextId(); 43 | 44 | /** 45 | * return a used Object ID back to the pool 46 | * @param id 47 | */ 48 | public abstract void releaseId(int id); 49 | 50 | public abstract int size(); 51 | } 52 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/thread/entity/ScheduleDestroyTask.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.thread.entity; 2 | 3 | import com.shnok.javaserver.model.object.entity.Entity; 4 | import lombok.extern.log4j.Log4j2; 5 | 6 | @Log4j2 7 | // Task to destroy object based on delay 8 | public class ScheduleDestroyTask implements Runnable { 9 | private final Entity entity; 10 | 11 | public ScheduleDestroyTask(Entity entity){ 12 | this.entity = entity; 13 | } 14 | 15 | @Override 16 | public void run() { 17 | log.debug("Execute schedule destroy object"); 18 | if (entity != null) { 19 | entity.destroy(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/thread/entity/ScheduleHitTask.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.thread.entity; 2 | 3 | 4 | import com.shnok.javaserver.dto.external.serverpackets.ApplyDamagePacket; 5 | import com.shnok.javaserver.model.object.entity.Entity; 6 | import lombok.extern.log4j.Log4j2; 7 | 8 | @Log4j2 9 | // Task to apply damage based on delay 10 | public class ScheduleHitTask implements Runnable { 11 | private final Entity attacker; 12 | private final Entity hitTarget; 13 | private final int damage; 14 | private final boolean criticalHit; 15 | private final boolean miss; 16 | private final byte shield; 17 | private final boolean soulshot; 18 | private final ApplyDamagePacket attack; 19 | 20 | public ScheduleHitTask(ApplyDamagePacket attack, Entity attacker, Entity hitTarget, int damage, boolean criticalHit, 21 | boolean miss, boolean soulshot, byte shield) { 22 | this.attacker = attacker; 23 | this.hitTarget = hitTarget; 24 | this.damage = damage; 25 | this.criticalHit = criticalHit; 26 | this.miss = miss; 27 | this.shield = shield; 28 | this.soulshot = soulshot; 29 | this.attack = attack; 30 | } 31 | 32 | @Override 33 | public void run() { 34 | try { 35 | attacker.onHitTimer(attack, hitTarget, damage, criticalHit, miss, soulshot, shield); 36 | } catch (Throwable e) { 37 | log.error(e); 38 | e.printStackTrace(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/thread/entity/ScheduleNotifyAITask.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.thread.entity; 2 | 3 | import com.shnok.javaserver.enums.Event; 4 | import com.shnok.javaserver.thread.ai.BaseAI; 5 | import lombok.extern.log4j.Log4j2; 6 | 7 | @Log4j2 8 | // Task to notify AI based on delay 9 | public class ScheduleNotifyAITask implements Runnable { 10 | 11 | private final Event event; 12 | private final BaseAI ai; 13 | 14 | public ScheduleNotifyAITask(BaseAI ai, Event event) { 15 | this.event = event; 16 | this.ai = ai; 17 | } 18 | 19 | @Override 20 | public void run() { 21 | try { 22 | ai.notifyEvent(event, null); 23 | } catch (Throwable t) { 24 | log.warn(t); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/util/ByteUtils.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.util; 2 | 3 | public class ByteUtils { 4 | public static int swapInt(int intValue) { 5 | int byte0 = ((intValue >> 24) & 0xFF); 6 | int byte1 = ((intValue >> 16) & 0xFF); 7 | int byte2 = ((intValue >> 8) & 0xFF); 8 | int byte3 = (intValue & 0xFF); 9 | return (byte3 << 24) + (byte2 << 16) + (byte1 << 8) + (byte0); 10 | } 11 | 12 | public static short swapShort(short shortValue) { 13 | byte byte1 = (byte) (shortValue & 0xFF); 14 | byte byte2 = (byte) ((shortValue >> 8) & 0xFF); 15 | 16 | return (short) ((byte1 << 8) | (byte2 & 0xFF)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/util/HexUtils.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.util; 2 | 3 | import com.shnok.javaserver.security.Rnd; 4 | 5 | import java.math.BigInteger; 6 | import java.util.Arrays; 7 | 8 | public class HexUtils { 9 | public static byte[] generateHex(int size) { 10 | byte[] array = new byte[size]; 11 | Rnd.nextBytes(array); 12 | return array; 13 | } 14 | 15 | public static String bytesToHex(byte[] bytes) { 16 | StringBuilder hexString = new StringBuilder(); 17 | for (byte b : bytes) { 18 | String hex = Integer.toHexString(0xFF & b); 19 | if (hex.length() == 1) { 20 | hexString.append('0'); // Pad with leading zero if necessary 21 | } 22 | hexString.append(hex); 23 | } 24 | return hexString.toString(); 25 | } 26 | 27 | public static byte[] toUnsignedByteArray(BigInteger value) { 28 | byte[] signedValue = value.toByteArray(); 29 | if(signedValue[0] != 0x00) { 30 | throw new IllegalArgumentException("value must be a positive BigInteger"); 31 | } 32 | return Arrays.copyOfRange(signedValue, 1, signedValue.length); 33 | } 34 | 35 | public static byte[] hexStringToByteArray(String hexString) { 36 | int len = hexString.length(); 37 | byte[] byteArray = new byte[len / 2]; 38 | for (int i = 0; i < len; i += 2) { 39 | byteArray[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) 40 | + Character.digit(hexString.charAt(i+1), 16)); 41 | } 42 | return byteArray; 43 | } 44 | } -------------------------------------------------------------------------------- /gameserver/src/main/java/com/shnok/javaserver/util/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.shnok.javaserver.util; 2 | 3 | public class TimeUtils { 4 | // Get the current in game time in hour 5 | public static float ticksToHour(long gameTicks, int tickDurationMs, int dayDurationMinutes) { 6 | float ticksPerDay = (float)dayDurationMinutes * 60 * 1000 / tickDurationMs; 7 | float currentHours = gameTicks / ticksPerDay * 24 % 24; 8 | 9 | return currentHours; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /gameserver/target/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | */ 3 | !.gitignore --------------------------------------------------------------------------------