├── koserver-game ├── bin │ └── .gitignore ├── config │ ├── koserver.game.properties │ ├── koserver.game.network.properties │ ├── koserver.game.player.properties │ ├── log4j.properties │ ├── koserver.game.global.properties │ ├── hibernate.cfg.xml │ └── hibernate-configuration-3.0.dtd ├── src │ └── koserver │ │ └── game │ │ ├── configuration │ │ ├── GameConfig.java │ │ ├── NetworkConfig.java │ │ ├── PlayerConfig.java │ │ └── GlobalConfig.java │ │ ├── enums │ │ ├── Opcodes.java │ │ └── GameSystem.java │ │ ├── tasks │ │ ├── TaskTypeEnum.java │ │ ├── AbstractTask.java │ │ └── player │ │ │ └── PlayerQuitTask.java │ │ ├── models │ │ ├── player │ │ │ ├── enums │ │ │ │ ├── PlayerMoveTypeEnum.java │ │ │ │ ├── PlayerRaceEnum.java │ │ │ │ └── PlayerClassEnum.java │ │ │ └── Player.java │ │ └── account │ │ │ └── Account.java │ │ ├── MainGame.java │ │ ├── services │ │ ├── NetworkService.java │ │ ├── ClientsCollector.java │ │ ├── DatabaseService.java │ │ ├── ConfigurationService.java │ │ ├── ThreadPoolService.java │ │ ├── PlayerService.java │ │ └── AccountService.java │ │ ├── database │ │ ├── dao │ │ │ ├── PlayerDAO.java │ │ │ └── AccountDAO.java │ │ └── entity │ │ │ └── AccountEntity.java │ │ ├── network │ │ └── PacketWriter.java │ │ ├── delegate │ │ ├── AccountDelegate.java │ │ └── PlayerDelegate.java │ │ └── mapper │ │ └── database │ │ ├── AccountMapper.java │ │ └── PlayerMapper.java ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── game-build.xml └── .classpath ├── koserver-login ├── bin │ └── .gitignore ├── config │ ├── koserver.login.network.properties │ ├── koserver.login.properties │ ├── log4j.properties │ ├── hibernate.cfg.xml │ └── hibernate-configuration-3.0.dtd ├── .settings │ ├── org.eclipse.ltk.core.refactoring.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ └── koserver │ │ └── login │ │ ├── configuration │ │ ├── AccountConfig.java │ │ ├── NetworkConfig.java │ │ └── LoginConfig.java │ │ ├── delegate │ │ ├── PatchListDelegate.java │ │ ├── ServerListDelegate.java │ │ └── AccountDelegate.java │ │ ├── enums │ │ └── Opcodes.java │ │ ├── MainLogin.java │ │ ├── database │ │ ├── entity │ │ │ ├── PatchEntity.java │ │ │ ├── ServerEntity.java │ │ │ └── AccountEntity.java │ │ └── dao │ │ │ ├── PatchListDAO.java │ │ │ ├── ServerListDAO.java │ │ │ └── AccountDAO.java │ │ ├── services │ │ ├── NetworkService.java │ │ ├── ClientsCollector.java │ │ ├── ConfigurationService.java │ │ ├── DatabaseService.java │ │ └── AccountService.java │ │ ├── network │ │ ├── PacketWriter.java │ │ └── PacketHandler.java │ │ └── models │ │ └── Account.java ├── .project ├── login-build.xml └── .classpath ├── koserver-common ├── bin │ └── .gitignore ├── src │ └── koserver │ │ └── common │ │ ├── entity │ │ ├── HasId.java │ │ └── AbstractEntity.java │ │ ├── models │ │ ├── HasUid.java │ │ └── AbstractModel.java │ │ ├── services │ │ ├── events │ │ │ └── ServiceEvent.java │ │ └── AbstractService.java │ │ ├── database │ │ ├── dao │ │ │ ├── exception │ │ │ │ └── DAONotFoundException.java │ │ │ ├── AbstractDAO.java │ │ │ └── DAOManager.java │ │ └── entity │ │ │ └── AbstractDatabaseEntity.java │ │ ├── network │ │ ├── crypt │ │ │ ├── CryptorKey.java │ │ │ ├── Cryptor.java │ │ │ └── CRC32.java │ │ ├── PacketHandler.java │ │ ├── SocketServer.java │ │ ├── config │ │ │ └── ServerConfig.java │ │ ├── PacketListener.java │ │ └── Packet.java │ │ ├── utils │ │ ├── DebugUtils.java │ │ ├── ByteArrayReader.java │ │ ├── HexDump.java │ │ ├── PrintUtils.java │ │ ├── PropertiesUtils.java │ │ └── ArrayUtils.java │ │ ├── enums │ │ ├── LoginResult.java │ │ └── AccountAuthority.java │ │ ├── xml │ │ ├── entity │ │ │ └── AbstractXMLEntity.java │ │ └── utils │ │ │ └── XmlMerger.java │ │ ├── config │ │ ├── PropertyTransformer.java │ │ ├── transformers │ │ │ ├── ClassTransformer.java │ │ │ ├── FileTransformer.java │ │ │ ├── StringTransformer.java │ │ │ ├── StringArrayTransformer.java │ │ │ ├── LocaleTransformer.java │ │ │ ├── LongTransformer.java │ │ │ ├── ByteTransformer.java │ │ │ ├── ShortTransformer.java │ │ │ ├── FloatTransformer.java │ │ │ ├── IntegerTransformer.java │ │ │ ├── PatternTransformer.java │ │ │ ├── DoubleTransformer.java │ │ │ ├── EnumTransformer.java │ │ │ ├── CharTransformer.java │ │ │ ├── BooleanTransformer.java │ │ │ └── InetSocketAddressTransformer.java │ │ ├── exception │ │ │ └── TransformationException.java │ │ ├── Property.java │ │ └── PropertyTransformerFactory.java │ │ └── mapper │ │ ├── xml │ │ ├── XMLMapper.java │ │ └── XMLListMapper.java │ │ ├── database │ │ └── DatabaseMapper.java │ │ └── MapperManager.java ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs └── .classpath ├── screenshots ├── 201501252345.jpg └── 201501272241.jpg ├── TODO.txt ├── README.md ├── .gitattributes └── .gitignore /koserver-game/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /koserver 2 | -------------------------------------------------------------------------------- /koserver-login/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /koserver 2 | -------------------------------------------------------------------------------- /koserver-common/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /koserver 2 | -------------------------------------------------------------------------------- /koserver-game/config/koserver.game.properties: -------------------------------------------------------------------------------- 1 | gameserver.version = 1886 -------------------------------------------------------------------------------- /screenshots/201501252345.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZeusAFK/koserver-java/HEAD/screenshots/201501252345.jpg -------------------------------------------------------------------------------- /screenshots/201501272241.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZeusAFK/koserver-java/HEAD/screenshots/201501272241.jpg -------------------------------------------------------------------------------- /koserver-game/config/koserver.game.network.properties: -------------------------------------------------------------------------------- 1 | gameserver.network.bind.host = * 2 | gameserver.network.bind.port = 15001 -------------------------------------------------------------------------------- /koserver-login/config/koserver.login.network.properties: -------------------------------------------------------------------------------- 1 | loginserver.network.bind.host = * 2 | loginserver.network.bind.port = 15100 -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/entity/HasId.java: -------------------------------------------------------------------------------- 1 | package koserver.common.entity; 2 | 3 | public interface HasId { 4 | public Integer getId(); 5 | } 6 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/models/HasUid.java: -------------------------------------------------------------------------------- 1 | package koserver.common.models; 2 | 3 | public interface HasUid { 4 | public int getUid(); 5 | } 6 | -------------------------------------------------------------------------------- /koserver-login/config/koserver.login.properties: -------------------------------------------------------------------------------- 1 | loginserver.version = 1886 2 | loginserver.ftp.url = 127.0.0.1 3 | loginserver.ftp.path = / 4 | account.autocreate = true -------------------------------------------------------------------------------- /koserver-login/.settings/org.eclipse.ltk.core.refactoring.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false 3 | -------------------------------------------------------------------------------- /koserver-game/config/koserver.game.player.properties: -------------------------------------------------------------------------------- 1 | player.name.pattern = [A-Za-z]* 2 | player.max.level = 83 3 | player.auto.save.delay = 900 4 | player.gain.hp.delay = 5 5 | player.gain.mp.delay = 5 -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/services/events/ServiceEvent.java: -------------------------------------------------------------------------------- 1 | package koserver.common.services.events; 2 | 3 | public interface ServiceEvent { 4 | void onInit(); 5 | void onDestroy(); 6 | } 7 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/entity/AbstractEntity.java: -------------------------------------------------------------------------------- 1 | package koserver.common.entity; 2 | 3 | public abstract class AbstractEntity implements HasId { 4 | 5 | @Override 6 | public Integer getId() { 7 | return 0; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /koserver-game/config/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=debug, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | 6 | log4j.logger.org.hibernate=error 7 | log4j.logger.org.apache.commons.beanutils=ERROR -------------------------------------------------------------------------------- /koserver-login/config/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=debug, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | 6 | log4j.logger.org.hibernate=error 7 | log4j.logger.org.apache.commons.beanutils=ERROR -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/configuration/GameConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.game.configuration; 2 | 3 | import koserver.common.config.Property; 4 | 5 | public class GameConfig { 6 | @Property(key = "gameserver.version", defaultValue = "1860") 7 | public static int GAME_VERSION; 8 | } 9 | -------------------------------------------------------------------------------- /koserver-game/config/koserver.game.global.properties: -------------------------------------------------------------------------------- 1 | global.name.banned.words = fuck,boobs,dick 2 | global.welcome.title = Knight Online Server 3 | global.welcome.content = Open source java server 4 | global.data.management.use.cache = false 5 | global.data.threadpool.pool.size = 3 6 | global.kill.rate = 1 -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | Working: 2 | Loginserver 3 | - Account login 4 | - Account auto register 5 | - Server list 6 | 7 | TODO: 8 | Loginserver 9 | - News 10 | - El Morad/Karus king and king notice 11 | 12 | Common 13 | Handle packet secuence id and checksum in packet 14 | 15 | Gameserver 16 | ALL :) -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/configuration/AccountConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.login.configuration; 2 | 3 | import koserver.common.config.Property; 4 | 5 | public class AccountConfig { 6 | 7 | @Property(key = "account.autocreate", defaultValue = "true") 8 | public static boolean ACCOUNT_AUTOCREATE; 9 | } 10 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/database/dao/exception/DAONotFoundException.java: -------------------------------------------------------------------------------- 1 | package koserver.common.database.dao.exception; 2 | 3 | public class DAONotFoundException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 6835686733723787299L; 6 | 7 | public DAONotFoundException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/configuration/NetworkConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.game.configuration; 2 | 3 | import koserver.common.config.Property; 4 | 5 | public class NetworkConfig { 6 | @Property(key = "gameserver.network.bind.host", defaultValue = "*") 7 | public static String GAME_BIND_ADDRESS; 8 | 9 | @Property(key = "gameserver.network.bind.port", defaultValue = "80") 10 | public static int GAME_BIND_PORT; 11 | } 12 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/configuration/NetworkConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.login.configuration; 2 | 3 | import koserver.common.config.Property; 4 | 5 | public class NetworkConfig { 6 | @Property(key = "loginserver.network.bind.host", defaultValue = "*") 7 | public static String LOGIN_BIND_ADDRESS; 8 | 9 | @Property(key = "loginserver.network.bind.port", defaultValue = "80") 10 | public static int LOGIN_BIND_PORT; 11 | } 12 | -------------------------------------------------------------------------------- /koserver-game/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | koserver-game 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /koserver-login/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | koserver-login 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/delegate/PatchListDelegate.java: -------------------------------------------------------------------------------- 1 | package koserver.login.delegate; 2 | 3 | import java.util.List; 4 | 5 | import koserver.common.database.dao.DAOManager; 6 | import koserver.login.database.dao.PatchListDAO; 7 | import koserver.login.database.entity.PatchEntity; 8 | 9 | public class PatchListDelegate { 10 | public static List getPatchs() { 11 | return DAOManager.getDAO(PatchListDAO.class).readAll(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /koserver-common/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | koserver-common 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/delegate/ServerListDelegate.java: -------------------------------------------------------------------------------- 1 | package koserver.login.delegate; 2 | 3 | import java.util.List; 4 | 5 | import koserver.common.database.dao.DAOManager; 6 | import koserver.login.database.dao.ServerListDAO; 7 | import koserver.login.database.entity.ServerEntity; 8 | 9 | public class ServerListDelegate { 10 | public static List getServers() { 11 | return DAOManager.getDAO(ServerListDAO.class).readAll(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/enums/Opcodes.java: -------------------------------------------------------------------------------- 1 | package koserver.login.enums; 2 | 3 | public class Opcodes { 4 | public static final short LS_VERSION_REQ = 0x0001; 5 | public static final short LS_DOWNLOADINFO_REQ = 0x0002; 6 | public static final short LS_CRYPTION = 0x00F2; 7 | public static final short LS_LOGIN = 0x00F3; 8 | public static final short LS_SERVERLIST = 0x00F5; 9 | public static final short LS_UNKNOW_F7 = 0x00F7; 10 | public static final short LS_NEWS = 0x00F6; 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # koserver-java 2 | ## Knight Online Server written in java 3 | 4 | Knight Online open source server written in java and using hibernate. Some code is based on Twostars KO C++ project and Angelis Tera java project. 5 | 6 | ## Screenshots 7 | 8 | Working login and server list 9 | ![Alt text](/screenshots/201501252345.jpg?raw=true "Server list implemented") 10 | 11 | 12 | Implemented character creation 13 | ![Alt text](/screenshots/201501272241.jpg?raw=true "Character creation implemented") 14 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/crypt/CryptorKey.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network.crypt; 2 | 3 | import java.math.BigInteger; 4 | import java.util.Random; 5 | 6 | public class CryptorKey { 7 | 8 | public static BigInteger generateKey() { 9 | while (true) { 10 | BigInteger n = new BigInteger(64, new Random(System.nanoTime())); 11 | if (n.toString().length() == 20) { 12 | return n; 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/enums/Opcodes.java: -------------------------------------------------------------------------------- 1 | package koserver.game.enums; 2 | 3 | public class Opcodes { 4 | public static final short GS_VERSION_CHECK = 0x002B; 5 | public static final short GS_LOGIN = 0x0001; 6 | public static final short GS_NATION_SELECT = 0x0005; 7 | public static final short GS_ALLCHAR_INFO_REQ = 0x000C; 8 | public static final short GS_CREATE_CHARACTER = 0x0002; 9 | public static final short GS_SELECT_CHARACTER = 0x0004; 10 | public static final short GS_SPEEDHACK_CHECK = 0x0041; 11 | } 12 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/configuration/LoginConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.login.configuration; 2 | 3 | import koserver.common.config.Property; 4 | 5 | public class LoginConfig { 6 | @Property(key = "loginserver.version", defaultValue = "1860") 7 | public static int LOGIN_VERSION; 8 | 9 | @Property(key = "loginserver.ftp.url", defaultValue = "127.0.0.1") 10 | public static String LOGIN_FTP_URL; 11 | 12 | @Property(key = "loginserver.ftp.path", defaultValue = "/") 13 | public static String LOGIN_FTP_PATH; 14 | } 15 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/utils/DebugUtils.java: -------------------------------------------------------------------------------- 1 | package koserver.common.utils; 2 | 3 | public class DebugUtils { 4 | 5 | static boolean isDebugEnabled = true; 6 | static boolean printConsole = true; 7 | static boolean printFile = true; 8 | 9 | public static void Trace(String data) { 10 | if (isDebugEnabled) { 11 | if (printConsole) { 12 | System.out.println(data); 13 | } 14 | // TODO: Print to file if printFile is true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/enums/LoginResult.java: -------------------------------------------------------------------------------- 1 | package koserver.common.enums; 2 | 3 | public class LoginResult { 4 | 5 | public static final int AUTH_SUCCESS = 0x01; 6 | public static final int AUTH_NOT_FOUND = 0x02; 7 | public static final int AUTH_INVALID = 0x03; 8 | public static final int AUTH_BANNED = 0x04; 9 | public static final int AUTH_IN_GAME = 0x05; 10 | public static final int AUTH_ERROR = 0x06; 11 | public static final int AUTH_AGREEMENT = 0xF; 12 | public static final int AUTH_FAILED = 0xF; 13 | } -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/xml/entity/AbstractXMLEntity.java: -------------------------------------------------------------------------------- 1 | package koserver.common.xml.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.xml.bind.Unmarshaller; 6 | 7 | import koserver.common.entity.AbstractEntity; 8 | 9 | public abstract class AbstractXMLEntity extends AbstractEntity implements Serializable { 10 | 11 | private static final long serialVersionUID = -3825172794095209401L; 12 | 13 | public abstract void afterUnmarshalling(Unmarshaller unmarshaller); 14 | 15 | public abstract void onLoad(); 16 | } 17 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/tasks/TaskTypeEnum.java: -------------------------------------------------------------------------------- 1 | package koserver.game.tasks; 2 | 3 | public enum TaskTypeEnum { 4 | PLAYER_QUIT, 5 | PLAYER_QUIT_TO_PLAYER_LIST, 6 | PLAYER_DELETE, 7 | PLAYER_AUTO_SAVE, 8 | PLAYER_CHECK_AGGRO, 9 | PLAYER_STATS_MODIFIER, 10 | PLAYER_ABNORMALITY_END, 11 | 12 | TERA_OBJECT_RESPAWN, 13 | TERA_OBJECT_DESPAWN, 14 | 15 | ITEM_FREE_LOOT, 16 | 17 | PEGASUS_FLY_START, 18 | PEGASUS_FLY_END, 19 | 20 | REQUEST_AUTO_CANCEL, 21 | ; 22 | } 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/database/dao/AbstractDAO.java: -------------------------------------------------------------------------------- 1 | package koserver.common.database.dao; 2 | 3 | import koserver.common.database.entity.AbstractDatabaseEntity; 4 | 5 | import org.hibernate.Session; 6 | 7 | public abstract class AbstractDAO { 8 | 9 | protected final Session session = this.getSession(); 10 | 11 | public abstract void create(E entity); 12 | public abstract E read(Integer id); 13 | public abstract void update(E entity); 14 | public abstract void delete(E entity); 15 | 16 | protected abstract Session getSession(); 17 | } 18 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/PacketHandler.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network; 2 | 3 | import koserver.common.services.AbstractService; 4 | 5 | 6 | /** 7 | * @author Kurokami Clase utilizada para controlar paquetes. 8 | */ 9 | /** 10 | * @author Kurokami 11 | * 12 | */ 13 | public interface PacketHandler { 14 | public void Initialize(AbstractService clientService); 15 | /** 16 | * Maneja un paquete en base al opcode. 17 | * 18 | * @param packet 19 | * Instancia de la clase Packet que contiene los datos del 20 | * paquete. 21 | */ 22 | public void handlePacket(Packet packet); 23 | } -------------------------------------------------------------------------------- /koserver-game/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /koserver-common/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /koserver-login/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/PropertyTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.exception.TransformationException; 6 | 7 | public interface PropertyTransformer { 8 | 9 | /** 10 | * This method actually transforms value to object instance 11 | * 12 | * @param value value that will be transformed 13 | * @param field value will be assigned to this field 14 | * @return result of transformation 15 | * @throws TransformationException if something went wrong 16 | */ 17 | public T transform(String value, Field field) throws TransformationException; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/configuration/PlayerConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.game.configuration; 2 | 3 | import koserver.common.config.Property; 4 | 5 | public class PlayerConfig { 6 | 7 | @Property(key = "player.name.pattern", defaultValue = "[A-Za-z]*") 8 | public static String PLAYER_NAME_PATTERN; 9 | 10 | @Property(key = "player.max.level", defaultValue = "60") 11 | public static int PLAYER_MAX_LEVEL; 12 | 13 | @Property(key = "player.auto.save.delay", defaultValue = "900") 14 | public static int PLAYER_AUTO_SAVE_DELAY; 15 | 16 | @Property(key = "player.gain.hp.delay", defaultValue = "5") 17 | public static int PLAYER_GAIN_HP_DELAY; 18 | 19 | @Property(key = "player.gain.mp.delay", defaultValue = "5") 20 | public static int PLAYER_GAIN_MP_DELAY; 21 | } -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/mapper/xml/XMLMapper.java: -------------------------------------------------------------------------------- 1 | package koserver.common.mapper.xml; 2 | 3 | import koserver.common.entity.AbstractEntity; 4 | import koserver.common.models.AbstractModel; 5 | import koserver.common.xml.entity.AbstractXMLEntity; 6 | 7 | public abstract class XMLMapper { 8 | 9 | public final E map(final M model) { 10 | return this.map(model, null); 11 | } 12 | 13 | public final M map(final E entity) { 14 | return this.map(entity, null); 15 | } 16 | 17 | public abstract E map(final M model, AbstractEntity linkedEntity); 18 | public abstract M map(final E entity, AbstractModel linkedModel); 19 | public abstract boolean equals(M model, E entity); 20 | } 21 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/models/player/enums/PlayerMoveTypeEnum.java: -------------------------------------------------------------------------------- 1 | package koserver.game.models.player.enums; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | public enum PlayerMoveTypeEnum { 6 | NORMAL(0), STUCK(2), JUMP_START(5), JUMP_BLOCK(6), JUMP_END(7), FALL(10); 7 | 8 | public final short value; 9 | 10 | PlayerMoveTypeEnum(final int value) { 11 | this.value = (short) value; 12 | } 13 | 14 | public static PlayerMoveTypeEnum fromValue(final short value) { 15 | for (final PlayerMoveTypeEnum playerMoveType : PlayerMoveTypeEnum.values()) { 16 | if (playerMoveType.value == value) { 17 | return playerMoveType; 18 | } 19 | } 20 | 21 | Logger.getLogger(PlayerMoveTypeEnum.class.getName()).error("Can't find PlayerMoveTypeEnum with value " + value); 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/services/AbstractService.java: -------------------------------------------------------------------------------- 1 | package koserver.common.services; 2 | 3 | import koserver.common.services.events.ServiceEvent; 4 | 5 | public abstract class AbstractService implements ServiceEvent { 6 | 7 | private boolean started; 8 | 9 | public AbstractService() { 10 | } 11 | 12 | public final void start() { 13 | if (this.started) { 14 | return; 15 | } 16 | 17 | this.onInit(); 18 | this.started = true; 19 | } 20 | 21 | public final void stop() { 22 | if (!this.started) { 23 | return; 24 | } 25 | 26 | this.onDestroy(); 27 | this.started = false; 28 | } 29 | 30 | public final void restart() { 31 | this.stop(); 32 | this.start(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/models/player/enums/PlayerRaceEnum.java: -------------------------------------------------------------------------------- 1 | package koserver.game.models.player.enums; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | public enum PlayerRaceEnum { 6 | UNKNOW(0), EL_MORAD_BARBARIAN(11), EL_MORAD_MALE(12), EL_MORAD_FEMALE(13), KARUS_ARCH_TUAREK(1), KARUS_TUAREK(2), KARUS_WRINKLE_TUAREK(3), KARUS_PURI_TUAREK(4); 7 | 8 | public final int value; 9 | 10 | PlayerRaceEnum(final int value) { 11 | this.value = value; 12 | } 13 | 14 | public static PlayerRaceEnum fromValue(final int value) { 15 | for (final PlayerRaceEnum race : PlayerRaceEnum.values()) { 16 | if (race.value == value) { 17 | return race; 18 | } 19 | } 20 | 21 | Logger.getLogger(PlayerRaceEnum.class.getName()).error("Can't find NationEnum with value " + value); 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/mapper/database/DatabaseMapper.java: -------------------------------------------------------------------------------- 1 | package koserver.common.mapper.database; 2 | 3 | import koserver.common.database.entity.AbstractDatabaseEntity; 4 | import koserver.common.entity.AbstractEntity; 5 | import koserver.common.models.AbstractModel; 6 | 7 | 8 | public abstract class DatabaseMapper { 9 | 10 | public final E map(final M model) { 11 | return this.map(model, null); 12 | } 13 | 14 | public final M map(final E entity) { 15 | return this.map(entity, null); 16 | } 17 | 18 | public abstract E map(final M model, AbstractEntity linkedEntity); 19 | public abstract M map(final E entity, AbstractModel linkedModel); 20 | public abstract boolean equals(M model, E entity); 21 | } 22 | -------------------------------------------------------------------------------- /koserver-game/config/hibernate.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | org.hibernate.dialect.MySQLDialect 8 | com.mysql.jdbc.Driver 9 | 10 | jdbc:mysql://localhost/koserver 11 | root 12 | root 13 | false 14 | 15 | update 16 | 17 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/mapper/xml/XMLListMapper.java: -------------------------------------------------------------------------------- 1 | package koserver.common.mapper.xml; 2 | 3 | import java.util.List; 4 | 5 | import koserver.common.entity.AbstractEntity; 6 | import koserver.common.models.AbstractModel; 7 | import koserver.common.xml.entity.AbstractXMLEntity; 8 | 9 | public abstract class XMLListMapper { 10 | 11 | public final E map(final List models) { 12 | return this.map(models, null); 13 | } 14 | 15 | public final List map(final E entity) { 16 | return this.map(entity, null); 17 | } 18 | 19 | public abstract E map(final List models, AbstractEntity linkedEntity); 20 | public abstract List map(final E entity, AbstractModel linkedModel); 21 | public abstract boolean equals(M model, E entity); 22 | } 23 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/enums/AccountAuthority.java: -------------------------------------------------------------------------------- 1 | package koserver.common.enums; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public enum AccountAuthority { 7 | NORMAL(1), 8 | BANNED(0) 9 | ; 10 | 11 | public final int value; 12 | 13 | AccountAuthority(final int value) { 14 | this.value = value; 15 | } 16 | 17 | public int getValue() { 18 | return value; 19 | } 20 | 21 | private static final Map _map = new HashMap(); 22 | static 23 | { 24 | for (AccountAuthority authority : AccountAuthority.values()) 25 | _map.put(authority.value, authority); 26 | } 27 | 28 | public static AccountAuthority from(int value) 29 | { 30 | return _map.get(value); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /koserver-login/config/hibernate.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | org.hibernate.dialect.MySQLDialect 8 | com.mysql.jdbc.Driver 9 | 10 | jdbc:mysql://localhost/koserver 11 | root 12 | root 13 | false 14 | 15 | update 16 | 17 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/MainLogin.java: -------------------------------------------------------------------------------- 1 | package koserver.login; 2 | 3 | import koserver.common.utils.PrintUtils; 4 | import koserver.login.configuration.LoginConfig; 5 | import koserver.login.services.ConfigurationService; 6 | import koserver.login.services.DatabaseService; 7 | import koserver.login.services.NetworkService; 8 | 9 | public class MainLogin { 10 | 11 | public static void main(String[] args) { 12 | final long start = System.currentTimeMillis(); 13 | 14 | PrintUtils.printSection("Services"); 15 | ConfigurationService.getInstance().start(); 16 | DatabaseService.getInstance().start(); 17 | NetworkService.getInstance().start(); 18 | PrintUtils.printSection("Launching login server version: " + LoginConfig.LOGIN_VERSION); 19 | 20 | System.out.println("Server started in " + ((System.currentTimeMillis() - start) / 1000) + " seconds"); 21 | } 22 | } -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/ClassTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class ClassTransformer implements PropertyTransformer> { 9 | /** 10 | * Shared instance. 11 | */ 12 | public static final ClassTransformer SHARED_INSTANCE = new ClassTransformer(); 13 | 14 | public Class transform(String value, Field field) throws TransformationException { 15 | try { 16 | return Class.forName(value, false, getClass().getClassLoader()); 17 | } 18 | catch (ClassNotFoundException e) { 19 | throw new TransformationException("Cannot find class with name '" + value + "'"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/delegate/AccountDelegate.java: -------------------------------------------------------------------------------- 1 | package koserver.login.delegate; 2 | 3 | import koserver.common.database.dao.DAOManager; 4 | import koserver.login.database.dao.AccountDAO; 5 | import koserver.login.database.entity.AccountEntity; 6 | 7 | public class AccountDelegate { 8 | 9 | public static void createAccountEntity(final AccountEntity entity) { 10 | DAOManager.getDAO(AccountDAO.class).create(entity); 11 | } 12 | 13 | public static AccountEntity readAccountEntityById(final Integer id) { 14 | return DAOManager.getDAO(AccountDAO.class).read(id); 15 | } 16 | 17 | public static AccountEntity readAccountEntityByLogin(final String login) { 18 | return DAOManager.getDAO(AccountDAO.class).readByLogin(login); 19 | } 20 | 21 | public static void updateAccountEntity(final AccountEntity entity) { 22 | DAOManager.getDAO(AccountDAO.class).update(entity); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/tasks/AbstractTask.java: -------------------------------------------------------------------------------- 1 | package koserver.game.tasks; 2 | 3 | import koserver.game.services.ThreadPoolService; 4 | 5 | public abstract class AbstractTask { 6 | 7 | protected final T linkedObject; 8 | protected final TaskTypeEnum taskType; 9 | protected final boolean repeat = false; 10 | 11 | public AbstractTask(final T linkedObject, final TaskTypeEnum taskType) { 12 | this.linkedObject = linkedObject; 13 | this.taskType = taskType; 14 | } 15 | 16 | public T getLinkedObject() { 17 | return linkedObject; 18 | } 19 | 20 | public TaskTypeEnum getTaskType() { 21 | return taskType; 22 | } 23 | 24 | public final void cancel() { 25 | ThreadPoolService.getInstance().cancelTask(this.linkedObject, this.taskType); 26 | } 27 | 28 | public abstract void execute(); 29 | } 30 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/database/entity/PatchEntity.java: -------------------------------------------------------------------------------- 1 | package koserver.login.database.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.Table; 6 | 7 | import koserver.common.database.entity.AbstractDatabaseEntity; 8 | 9 | @Entity 10 | @Table(name="patch") 11 | public class PatchEntity extends AbstractDatabaseEntity{ 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | @Column(name="version") 16 | private int version; 17 | 18 | @Column(name="filename") 19 | private String filename; 20 | 21 | public int getVersion(){ 22 | return version; 23 | } 24 | 25 | public void setVersion(final int version){ 26 | this.version = version; 27 | } 28 | 29 | public String getFileName(){ 30 | return filename; 31 | } 32 | 33 | public void setFileName(String filename){ 34 | this.filename = filename; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/SocketServer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | 7 | import koserver.common.network.config.ServerConfig; 8 | 9 | public class SocketServer { 10 | 11 | private ServerSocket socket; 12 | private int port; 13 | 14 | public SocketServer(ServerConfig config) { 15 | this.port = config.getPort(); 16 | } 17 | 18 | public void close() throws IOException { 19 | socket.close(); 20 | } 21 | 22 | public void open() throws IOException { 23 | socket = new ServerSocket(port); 24 | } 25 | 26 | public Socket waitForConnection() { 27 | try { 28 | return socket.accept(); 29 | } catch (IOException e) { 30 | return null; 31 | } 32 | } 33 | 34 | public boolean isConnected(){ 35 | return !socket.isClosed(); 36 | } 37 | 38 | public int getPort(){ 39 | return socket.getLocalPort(); 40 | } 41 | } -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/FileTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.io.File; 4 | import java.lang.reflect.Field; 5 | 6 | import koserver.common.config.PropertyTransformer; 7 | import koserver.common.config.exception.TransformationException; 8 | 9 | public class FileTransformer implements PropertyTransformer { 10 | /** 11 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 12 | */ 13 | public static final FileTransformer SHARED_INSTANCE = new FileTransformer(); 14 | 15 | /** 16 | * Transforms String to the file 17 | * 18 | * @param value value that will be transformed 19 | * @param field value will be assigned to this field 20 | * @return File object that represents string 21 | */ 22 | public File transform(String value, Field field) throws TransformationException { 23 | return new File(value); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/StringTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class StringTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final StringTransformer SHARED_INSTANCE = new StringTransformer(); 13 | 14 | /** 15 | * Just returns value object 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return return value object 20 | * @throws TransformationException never thrown 21 | */ 22 | public String transform(String value, Field field) throws TransformationException { 23 | return value; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/configuration/GlobalConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.game.configuration; 2 | 3 | import koserver.common.config.Property; 4 | 5 | public class GlobalConfig { 6 | @Property(key = "global.name.banned.words", defaultValue = "fuck,boobs,dick") 7 | public static String[] GLOBAL_NAME_BANNED_WORDS; 8 | 9 | @Property(key = "global.welcome.title", defaultValue = "Knight Online Server") 10 | public static String GLOBAL_WELCOME_TITLE; 11 | 12 | @Property(key = "global.welcome.content", defaultValue = "Open source java server") 13 | public static String GLOBAL_WELCOME_CONTENT; 14 | 15 | @Property(key = "global.data.management.use.cache", defaultValue = "true") 16 | public static boolean GLOBAL_DATA_MANAGEMENT_USE_CACHE; 17 | 18 | @Property(key = "global.data.threadpool.pool.size", defaultValue = "3") 19 | public static int GLOBAL_THREADPOOL_POOL_SIZE; 20 | 21 | @Property(key = "global.kill.rate", defaultValue = "1") 22 | public static int GLOBAL_KILL_RATE; 23 | } 24 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/config/ServerConfig.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network.config; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.net.SocketAddress; 5 | 6 | 7 | public class ServerConfig { 8 | 9 | private final String address; 10 | private final int port; 11 | 12 | public ServerConfig(final String address, final int port) { 13 | this.address = address; 14 | this.port = port; 15 | } 16 | 17 | public final int getPort() { 18 | return port; 19 | } 20 | 21 | public final String getAddress() { 22 | return this.address; 23 | } 24 | 25 | public final SocketAddress getInetSocketAddress() { 26 | SocketAddress inetSocketAddress = null; 27 | if ("*".equals(this.address)) { 28 | inetSocketAddress = new InetSocketAddress(this.port); 29 | } else { 30 | inetSocketAddress = new InetSocketAddress(this.address, this.port); 31 | } 32 | return inetSocketAddress ; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/StringArrayTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class StringArrayTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final StringArrayTransformer SHARED_INSTANCE = new StringArrayTransformer(); 13 | 14 | /** 15 | * Just returns value object 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return return value object 20 | * @throws TransformationException never thrown 21 | */ 22 | public String[] transform(String value, Field field) throws TransformationException { 23 | return value.split(","); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/LocaleTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.Locale; 5 | 6 | import org.apache.commons.lang3.LocaleUtils; 7 | 8 | import koserver.common.config.PropertyTransformer; 9 | import koserver.common.config.exception.TransformationException; 10 | 11 | public class LocaleTransformer implements PropertyTransformer { 12 | /** 13 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 14 | */ 15 | public static final LocaleTransformer SHARED_INSTANCE = new LocaleTransformer(); 16 | 17 | /** 18 | * Transforms String to the file 19 | * 20 | * @param value value that will be transformed 21 | * @param field value will be assigned to this field 22 | * @return File object that represents string 23 | */ 24 | public Locale transform(String value, Field field) throws TransformationException { 25 | return LocaleUtils.toLocale(value); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/MainGame.java: -------------------------------------------------------------------------------- 1 | package koserver.game; 2 | 3 | import koserver.common.utils.PrintUtils; 4 | import koserver.game.configuration.GameConfig; 5 | import koserver.game.services.ConfigurationService; 6 | import koserver.game.services.DatabaseService; 7 | import koserver.game.services.NetworkService; 8 | import koserver.game.services.PlayerService; 9 | import koserver.game.services.ThreadPoolService; 10 | 11 | public class MainGame { 12 | 13 | public static void main(String[] args) { 14 | final long start = System.currentTimeMillis(); 15 | 16 | PrintUtils.printSection("Services"); 17 | ConfigurationService.getInstance().start(); 18 | DatabaseService.getInstance().start(); 19 | NetworkService.getInstance().start(); 20 | PlayerService.getInstance().start(); 21 | ThreadPoolService.getInstance().start(); 22 | PrintUtils.printSection("Launching game server version: " + GameConfig.GAME_VERSION); 23 | 24 | System.out.println("Server started in " + ((System.currentTimeMillis() - start) / 1000) + " seconds"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/tasks/player/PlayerQuitTask.java: -------------------------------------------------------------------------------- 1 | package koserver.game.tasks.player; 2 | 3 | import koserver.game.models.account.Account; 4 | import koserver.game.models.player.Player; 5 | import koserver.game.services.AccountService; 6 | import koserver.game.services.PlayerService; 7 | import koserver.game.tasks.AbstractTask; 8 | import koserver.game.tasks.TaskTypeEnum; 9 | 10 | public class PlayerQuitTask extends AbstractTask { 11 | 12 | public PlayerQuitTask(final Player linkedObject) { 13 | super(linkedObject, TaskTypeEnum.PLAYER_QUIT); 14 | } 15 | 16 | @Override 17 | public void execute() { 18 | final Player player = this.linkedObject; 19 | if (player == null) { 20 | return; 21 | } 22 | 23 | final Account account = player.getAccount(); 24 | if (account == null) { 25 | return; 26 | } 27 | 28 | final AccountService connection = account.getConnection(); 29 | if (connection == null) { 30 | return; 31 | } 32 | 33 | PlayerService.getInstance().onPlayerDisconnect(player); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.war 8 | *.ear 9 | 10 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 11 | hs_err_pid* 12 | 13 | # ========================= 14 | # Operating System Files 15 | # ========================= 16 | 17 | # OSX 18 | # ========================= 19 | 20 | .DS_Store 21 | .AppleDouble 22 | .LSOverride 23 | 24 | # Icon must end with two \r 25 | Icon 26 | 27 | # Thumbnails 28 | ._* 29 | 30 | # Files that might appear on external disk 31 | .Spotlight-V100 32 | .Trashes 33 | 34 | # Directories potentially created on remote AFP share 35 | .AppleDB 36 | .AppleDesktop 37 | Network Trash Folder 38 | Temporary Items 39 | .apdisk 40 | 41 | # Windows 42 | # ========================= 43 | 44 | # Windows image file caches 45 | Thumbs.db 46 | ehthumbs.db 47 | 48 | # Folder config file 49 | Desktop.ini 50 | 51 | # Recycle Bin used on file shares 52 | $RECYCLE.BIN/ 53 | 54 | # Windows Installer files 55 | *.cab 56 | *.msi 57 | *.msm 58 | *.msp 59 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/LongTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class LongTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final LongTransformer SHARED_INSTANCE = new LongTransformer(); 13 | 14 | /** 15 | * Transforms value to long 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Long that represents value 20 | * @throws TransformationException if something went wrong 21 | */ 22 | public Long transform(String value, Field field) throws TransformationException { 23 | try { 24 | return Long.decode(value); 25 | } 26 | catch (Exception e) { 27 | throw new TransformationException(e); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/ByteTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class ByteTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final ByteTransformer SHARED_INSTANCE = new ByteTransformer(); 13 | 14 | /** 15 | * Tansforms string to byte 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Byte object that represents value 20 | * @throws TransformationException if something went wrong 21 | */ 22 | public Byte transform(String value, Field field) throws TransformationException { 23 | try { 24 | return Byte.decode(value); 25 | } 26 | catch (Exception e) { 27 | throw new TransformationException(e); 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/ShortTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class ShortTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final ShortTransformer SHARED_INSTANCE = new ShortTransformer(); 13 | 14 | /** 15 | * Transforms value to short 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Short object that represents value 20 | * @throws TransformationException if something went wrong 21 | */ 22 | public Short transform(String value, Field field) throws TransformationException { 23 | try { 24 | return Short.decode(value); 25 | } 26 | catch (Exception e) { 27 | throw new TransformationException(e); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/FloatTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class FloatTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final FloatTransformer SHARED_INSTANCE = new FloatTransformer(); 13 | 14 | /** 15 | * Thransforms string to float 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Float that represents value 20 | * @throws TransformationException if something went wrong 21 | */ 22 | public Float transform(String value, Field field) throws TransformationException { 23 | try { 24 | return Float.parseFloat(value); 25 | } 26 | catch (Exception e) { 27 | throw new TransformationException(e); 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/IntegerTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class IntegerTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final IntegerTransformer SHARED_INSTANCE = new IntegerTransformer(); 13 | 14 | /** 15 | * Transforms value to integer 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Integer object that represents value 20 | * @throws TransformationException if something went wrong 21 | */ 22 | public Integer transform(String value, Field field) throws TransformationException { 23 | try { 24 | return Integer.decode(value); 25 | } 26 | catch (Exception e) { 27 | throw new TransformationException(e); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /koserver-login/login-build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/PatternTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.regex.Pattern; 5 | 6 | import koserver.common.config.PropertyTransformer; 7 | import koserver.common.config.exception.TransformationException; 8 | 9 | public class PatternTransformer implements PropertyTransformer { 10 | /** 11 | * Shared instance of this transformer 12 | */ 13 | public static final PatternTransformer SHARED_INSTANCE = new PatternTransformer(); 14 | 15 | /** 16 | * Transforms String to Pattern object 17 | * 18 | * @param value value that will be transformed 19 | * @param field value will be assigned to this field 20 | * @return Pattern Object 21 | * @throws TransformationException if pattern is not valid 22 | */ 23 | public Pattern transform(String value, Field field) throws TransformationException { 24 | try { 25 | return Pattern.compile(value); 26 | } 27 | catch (Exception e) { 28 | throw new TransformationException("Not valid RegExp: " + value, e); 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/DoubleTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class DoubleTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final DoubleTransformer SHARED_INSTANCE = new DoubleTransformer(); 13 | 14 | /** 15 | * Transforms string to required double 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Double that represents transformed string 20 | * @throws TransformationException if something went wrong 21 | */ 22 | public Double transform(String value, Field field) throws TransformationException { 23 | try { 24 | return Double.parseDouble(value); 25 | } 26 | catch (Exception e) { 27 | throw new TransformationException(e); 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/exception/TransformationException.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.exception; 2 | 3 | public class TransformationException extends RuntimeException { 4 | /** 5 | * SerialID 6 | */ 7 | private static final long serialVersionUID = -6641235751743285902L; 8 | 9 | /** 10 | * Creates new instance of exception 11 | */ 12 | public TransformationException() {} 13 | 14 | /** 15 | * Creates new instance of exception 16 | * 17 | * @param message exception message 18 | */ 19 | public TransformationException(String message) { 20 | super(message); 21 | } 22 | 23 | /** 24 | * Creates new instance of exception 25 | * 26 | * @param message exception message 27 | * @param cause exception that is the reason of this exception 28 | */ 29 | public TransformationException(String message, Throwable cause) { 30 | super(message, cause); 31 | } 32 | 33 | /** 34 | * Creates new instance of exception 35 | * 36 | * @param cause exception that is the reason of this exception 37 | */ 38 | public TransformationException(Throwable cause) { 39 | super(cause); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /koserver-game/game-build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /koserver-common/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/crypt/Cryptor.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network.crypt; 2 | 3 | import java.math.BigInteger; 4 | 5 | import koserver.common.utils.ArrayUtils; 6 | 7 | public class Cryptor { 8 | 9 | public static BigInteger privateKey = new BigInteger("1207500120128966", 16); 10 | BigInteger publicKey; 11 | BigInteger tKey; 12 | 13 | public Cryptor(BigInteger publicKey) { 14 | this.publicKey = publicKey; 15 | tKey = publicKey.xor(privateKey); 16 | } 17 | 18 | public byte[] EncryptionWithCRC32(byte[] data) { 19 | byte[] result = EncryptionFast(data); 20 | return result; 21 | } 22 | 23 | private byte[] EncryptionFast(byte[] data) { 24 | int length = data.length; 25 | byte[] result = new byte[length]; 26 | int lKey, rsk; 27 | int rKey = 2157; 28 | 29 | char[] pKey = new StringBuilder(ArrayUtils.hexToString(tKey.toString(16))).reverse().toString().toCharArray(); 30 | lKey = (length * 157) & 0xFF; 31 | 32 | for (int i = 0; i < length; i++) { 33 | rsk = (rKey >> 8) & 0xFF; 34 | result[i] = (byte) (((data[i] ^ rsk) ^ (int) pKey[(i % 8)]) ^ lKey); 35 | rKey *= 2171; 36 | } 37 | 38 | return result; 39 | } 40 | } -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/EnumTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class EnumTransformer implements PropertyTransformer> { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final EnumTransformer SHARED_INSTANCE = new EnumTransformer(); 13 | 14 | /** 15 | * Trnasforms string to enum 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Enum object representing the value 20 | * @throws TransformationException if somehting went wrong 21 | */ 22 | @SuppressWarnings({"unchecked", "rawtypes"}) 23 | public Enum transform(String value, Field field) throws TransformationException { 24 | Class clazz = (Class) field.getType(); 25 | 26 | try { 27 | return Enum.valueOf(clazz, value); 28 | } 29 | catch (Exception e) { 30 | throw new TransformationException(e); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/models/AbstractModel.java: -------------------------------------------------------------------------------- 1 | package koserver.common.models; 2 | 3 | import koserver.common.entity.HasId; 4 | 5 | public abstract class AbstractModel implements HasId { 6 | 7 | private Integer id; 8 | 9 | public AbstractModel(Integer id) { 10 | this.id = id; 11 | } 12 | 13 | public Integer getId() { 14 | return id; 15 | } 16 | 17 | public void setId(Integer id) { 18 | this.id = id; 19 | } 20 | 21 | @Override 22 | public int hashCode() { 23 | final int prime = 31; 24 | int result = 1; 25 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 26 | return result; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object obj) { 31 | if (this == obj) { 32 | return true; 33 | } 34 | if (obj == null) { 35 | return false; 36 | } 37 | if (!(obj instanceof AbstractModel)) { 38 | return false; 39 | } 40 | AbstractModel other = (AbstractModel) obj; 41 | if (id == null) { 42 | if (other.id != null) { 43 | return false; 44 | } 45 | } 46 | else if (!id.equals(other.id)) { 47 | return false; 48 | } 49 | return true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /koserver-login/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/CharTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class CharTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 11 | */ 12 | public static final CharTransformer SHARED_INSTANCE = new CharTransformer(); 13 | 14 | /** 15 | * Transforms string to character 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Character object that represents transformed string 20 | * @throws TransformationException if something went wrong 21 | */ 22 | public Character transform(String value, Field field) throws TransformationException { 23 | try { 24 | char[] chars = value.toCharArray(); 25 | if (chars.length > 1) { 26 | throw new TransformationException("To many characters in the value"); 27 | } 28 | 29 | return chars[0]; 30 | } 31 | catch (Exception e) { 32 | throw new TransformationException(e); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/models/player/enums/PlayerClassEnum.java: -------------------------------------------------------------------------------- 1 | package koserver.game.models.player.enums; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | public enum PlayerClassEnum { 6 | KARUS_WARRIOR_BEGGINER(101), KARUS_ROGUE_BEGGINER(102), KARUS_MAGICIAN_BEGGINER(103), KARUS_PRIEST_BEGGINER(104), KARUS_WARRIOR_SKILLED(105), KARUS_WARRIOR_MASTERED(106), KARUS_ROGUE_SKILLED(107), KARUS_ROGUE_MASTERED(108), KARUS_MAGICIAN_SKILLED( 7 | 109), KARUS_MAGICIAN_MASTERED(110), KARUS_PRIEST_SKILLED(111), KARUS_PRIEST_MASTERED(112), EL_MORAD_WARRIOR_BEGGINER(201), EL_MORAD_ROGUE_BEGGINER(202), EL_MORAD_MAGICIAN_BEGGINER(203), EL_MORAD_PRIEST_BEGGINER(204), EL_MORAD_WARRIOR_SKILLED( 8 | 205), EL_MORAD_WARRIOR_MASTERED(206), EL_MORAD_ROGUE_SKILLED(207), EL_MORAD_ROGUE_MASTERED(208), EL_MORAD_MAGICIAN_SKILLED(209), EL_MORAD_MAGICIAN_MASTERED(210), EL_MORAD_PRIEST_SKILLED(211), EL_MORAD_PRIEST_MASTERED(212); 9 | 10 | public final int value; 11 | 12 | PlayerClassEnum(final int value) { 13 | this.value = value; 14 | } 15 | 16 | public static PlayerClassEnum fromValue(final int value) { 17 | for (final PlayerClassEnum playerClass : PlayerClassEnum.values()) { 18 | if (playerClass.value == value) { 19 | return playerClass; 20 | } 21 | } 22 | 23 | Logger.getLogger(PlayerClassEnum.class.getName()).error("Can't find PlayerClassEnum with value " + value); 24 | return null; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/services/NetworkService.java: -------------------------------------------------------------------------------- 1 | package koserver.game.services; 2 | 3 | import java.io.IOException; 4 | 5 | import koserver.common.network.SocketServer; 6 | import koserver.common.network.config.ServerConfig; 7 | import koserver.common.services.AbstractService; 8 | import koserver.game.configuration.NetworkConfig; 9 | 10 | import org.apache.log4j.Logger; 11 | 12 | public class NetworkService extends AbstractService { 13 | 14 | private static Logger log = Logger.getLogger(NetworkService.class.getName()); 15 | 16 | private SocketServer server; 17 | 18 | private NetworkService() { 19 | } 20 | 21 | @Override 22 | public void onInit() { 23 | server = new SocketServer(new ServerConfig(NetworkConfig.GAME_BIND_ADDRESS, NetworkConfig.GAME_BIND_PORT)); 24 | try { 25 | server.open(); 26 | } catch (IOException e) { 27 | log.error("Error on sockets server startup: " + e.getMessage()); 28 | System.exit(0); 29 | } 30 | ClientsCollector clientsCollector = new ClientsCollector(server); 31 | Thread clientsCollectorThread = new Thread(clientsCollector); 32 | clientsCollectorThread.start(); 33 | log.info("NetworkService started"); 34 | } 35 | 36 | @Override 37 | public void onDestroy() { 38 | log.info("NetworkService stopped"); 39 | } 40 | 41 | public static NetworkService getInstance() { 42 | return SingletonHolder.instance; 43 | } 44 | 45 | private static class SingletonHolder { 46 | protected static final NetworkService instance = new NetworkService(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/services/NetworkService.java: -------------------------------------------------------------------------------- 1 | package koserver.login.services; 2 | 3 | import java.io.IOException; 4 | 5 | import koserver.common.network.SocketServer; 6 | import koserver.common.network.config.ServerConfig; 7 | import koserver.common.services.AbstractService; 8 | import koserver.login.configuration.NetworkConfig; 9 | 10 | import org.apache.log4j.Logger; 11 | 12 | public class NetworkService extends AbstractService { 13 | 14 | private static Logger log = Logger.getLogger(NetworkService.class.getName()); 15 | 16 | private SocketServer server; 17 | 18 | private NetworkService() { 19 | } 20 | 21 | @Override 22 | public void onInit() { 23 | server = new SocketServer(new ServerConfig(NetworkConfig.LOGIN_BIND_ADDRESS, NetworkConfig.LOGIN_BIND_PORT)); 24 | try { 25 | server.open(); 26 | } catch (IOException e) { 27 | log.error("Error on sockets server startup: " + e.getMessage()); 28 | System.exit(0); 29 | } 30 | ClientsCollector clientsCollector = new ClientsCollector(server); 31 | Thread clientsCollectorThread = new Thread(clientsCollector); 32 | clientsCollectorThread.start(); 33 | log.info("NetworkService started"); 34 | } 35 | 36 | @Override 37 | public void onDestroy() { 38 | log.info("NetworkService stopped"); 39 | } 40 | 41 | public static NetworkService getInstance() { 42 | return SingletonHolder.instance; 43 | } 44 | 45 | private static class SingletonHolder { 46 | protected static final NetworkService instance = new NetworkService(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/BooleanTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | import koserver.common.config.PropertyTransformer; 6 | import koserver.common.config.exception.TransformationException; 7 | 8 | public class BooleanTransformer implements PropertyTransformer { 9 | /** 10 | * Shared instance of this transformer, it's thread safe so no need to create multiple instances 11 | */ 12 | public static final BooleanTransformer SHARED_INSTANCE = new BooleanTransformer(); 13 | 14 | /** 15 | * Transforms string to boolean. 16 | * 17 | * @param value value that will be transformed 18 | * @param field value will be assigned to this field 19 | * @return Boolean object that represents transformed value 20 | * @throws TransformationException if something goes wrong 21 | */ 22 | public Boolean transform(String value, Field field) throws TransformationException { 23 | // We should have error here if value is not correct, default 24 | // "Boolean.parseBoolean" returns false if string 25 | // is not "true" ignoring case 26 | if ("true".equalsIgnoreCase(value) || "1".equals(value)) { 27 | return true; 28 | } else if ("false".equalsIgnoreCase(value) || "0".equals(value)) { 29 | return false; 30 | } else { 31 | throw new TransformationException("Invalid boolean string: " + value); 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /koserver-game/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/database/dao/DAOManager.java: -------------------------------------------------------------------------------- 1 | package koserver.common.database.dao; 2 | 3 | import java.util.Map; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import javolution.util.FastMap; 8 | import koserver.common.database.dao.exception.DAONotFoundException; 9 | import koserver.common.database.entity.AbstractDatabaseEntity; 10 | 11 | public class DAOManager { 12 | 13 | /** LOGGER */ 14 | private static final Logger log = Logger.getLogger(DAOManager.class.getName()); 15 | 16 | /** Collection of registered DAOs */ 17 | private static final Map> daoMap = new FastMap>(); 18 | 19 | private DAOManager() { 20 | // empty 21 | } 22 | 23 | public static > T getDAO(Class clazz) { 24 | DAOManager.ensureDAO(clazz); 25 | 26 | @SuppressWarnings("unchecked") 27 | T result = (T) daoMap.get(clazz.getName()); 28 | 29 | if (result == null) { 30 | throw new DAONotFoundException("DAO Not found " + clazz.getName()); 31 | } 32 | 33 | return result; 34 | } 35 | 36 | private static final > void ensureDAO(Class clazz) { 37 | AbstractDAO result = daoMap.get(clazz.getName()); 38 | if (result == null) { 39 | try { 40 | daoMap.put(clazz.getName(), clazz.newInstance()); 41 | log.info("Initiated DAO: " + clazz.getName()); 42 | } catch (Exception e) { 43 | throw new RuntimeException(e.getMessage(), e); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/services/ClientsCollector.java: -------------------------------------------------------------------------------- 1 | package koserver.login.services; 2 | 3 | import java.net.Socket; 4 | import java.util.ArrayList; 5 | 6 | import org.apache.log4j.Logger; 7 | 8 | import koserver.common.network.SocketServer; 9 | import koserver.common.services.AbstractService; 10 | 11 | public class ClientsCollector extends AbstractService implements Runnable { 12 | 13 | private static Logger log = Logger.getLogger(ClientsCollector.class.getName()); 14 | 15 | private SocketServer server; 16 | private ArrayList clients; 17 | 18 | public ClientsCollector(SocketServer server) { 19 | clients = new ArrayList(); 20 | this.server = server; 21 | } 22 | 23 | @Override 24 | public void run() { 25 | this.onInit(); 26 | while (server.isConnected()) { 27 | Socket clientSocket = server.waitForConnection(); 28 | //log.info("Connection received on port " + clientSocket.getLocalPort() + " from " + clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort()); 29 | if (clientSocket != null) { 30 | AccountService client = new AccountService(clientSocket); 31 | clients.add(client); 32 | Thread clientThread = new Thread(client); 33 | clientThread.start(); 34 | } 35 | } 36 | this.onDestroy(); 37 | } 38 | 39 | public ArrayList getClients() { 40 | return clients; 41 | } 42 | 43 | @Override 44 | public void onInit() { 45 | //log.info("Clients connections service started on port " + server.getPort()); 46 | } 47 | 48 | @Override 49 | public void onDestroy() { 50 | log.info("Stopping client connections service"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/services/ClientsCollector.java: -------------------------------------------------------------------------------- 1 | package koserver.game.services; 2 | 3 | import java.net.Socket; 4 | import java.util.ArrayList; 5 | 6 | import org.apache.log4j.Logger; 7 | 8 | import koserver.common.network.SocketServer; 9 | import koserver.common.services.AbstractService; 10 | 11 | public class ClientsCollector extends AbstractService implements Runnable { 12 | 13 | private static Logger log = Logger.getLogger(ClientsCollector.class.getName()); 14 | 15 | private SocketServer server; 16 | private ArrayList clients; 17 | 18 | public ClientsCollector(SocketServer server) { 19 | clients = new ArrayList(); 20 | this.server = server; 21 | } 22 | 23 | @Override 24 | public void run() { 25 | this.onInit(); 26 | while (server.isConnected()) { 27 | Socket clientSocket = server.waitForConnection(); 28 | // log.info("Connection received on port " + 29 | // clientSocket.getLocalPort() + " from " + 30 | // clientSocket.getInetAddress().getHostAddress() + ":" + 31 | // clientSocket.getPort()); 32 | if (clientSocket != null) { 33 | AccountService client = new AccountService(clientSocket); 34 | clients.add(client); 35 | Thread clientThread = new Thread(client); 36 | clientThread.start(); 37 | } 38 | } 39 | this.onDestroy(); 40 | } 41 | 42 | public ArrayList getClients() { 43 | return clients; 44 | } 45 | 46 | @Override 47 | public void onInit() { 48 | // log.info("Clients connections service started on port " + 49 | // server.getPort()); 50 | } 51 | 52 | @Override 53 | public void onDestroy() { 54 | log.info("Stopping client connections service"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/services/DatabaseService.java: -------------------------------------------------------------------------------- 1 | package koserver.game.services; 2 | 3 | import java.io.File; 4 | 5 | import koserver.common.services.AbstractService; 6 | import koserver.game.database.entity.AccountEntity; 7 | import koserver.game.database.entity.PlayerEntity; 8 | 9 | import org.apache.log4j.Logger; 10 | import org.hibernate.SessionFactory; 11 | import org.hibernate.cfg.AnnotationConfiguration; 12 | 13 | @SuppressWarnings("deprecation") 14 | public class DatabaseService extends AbstractService { 15 | 16 | private static Logger log = Logger.getLogger(DatabaseService.class.getName()); 17 | 18 | private AnnotationConfiguration annotationConfiguration; 19 | private SessionFactory sessionFactory; 20 | 21 | private DatabaseService() { 22 | try { 23 | this.annotationConfiguration = new AnnotationConfiguration().configure(new File("config/hibernate.cfg.xml")).addPackage("koserver.game.database.entity"); 24 | 25 | this.annotationConfiguration.addAnnotatedClass(PlayerEntity.class); 26 | this.annotationConfiguration.addAnnotatedClass(AccountEntity.class); 27 | 28 | this.sessionFactory = this.annotationConfiguration.buildSessionFactory(); 29 | } catch (final Throwable ex) { 30 | System.err.println("Initial SessionFactory creation failed." + ex); 31 | throw new ExceptionInInitializerError(ex); 32 | } 33 | } 34 | 35 | @Override 36 | public void onInit() { 37 | log.info("DatabaseService started"); 38 | } 39 | 40 | @Override 41 | public void onDestroy() { 42 | } 43 | 44 | public SessionFactory getSessionFactory() { 45 | return this.sessionFactory; 46 | } 47 | 48 | public static DatabaseService getInstance() { 49 | return SingletonHolder.instance; 50 | } 51 | 52 | private static class SingletonHolder { 53 | protected static final DatabaseService instance = new DatabaseService(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/transformers/InetSocketAddressTransformer.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config.transformers; 2 | 3 | import java.lang.reflect.Field; 4 | import java.net.InetAddress; 5 | import java.net.InetSocketAddress; 6 | 7 | import koserver.common.config.PropertyTransformer; 8 | import koserver.common.config.exception.TransformationException; 9 | 10 | public class InetSocketAddressTransformer implements PropertyTransformer { 11 | /** 12 | * Shared instance of this transformer. It's thread-safe so no need of multiple instances 13 | */ 14 | public static final InetSocketAddressTransformer SHARED_INSTANCE = new InetSocketAddressTransformer(); 15 | 16 | /** 17 | * Transforms string to InetSocketAddress 18 | * 19 | * @param value value that will be transformed 20 | * @param field value will be assigned to this field 21 | * @return InetSocketAddress that represetns value 22 | * @throws TransformationException if somehting went wrong 23 | */ 24 | public InetSocketAddress transform(String value, Field field) throws TransformationException { 25 | String[] parts = value.split(":"); 26 | 27 | if (parts.length != 2) { 28 | throw new TransformationException("Can't transform property, must be in format \"address:port\""); 29 | } 30 | 31 | try { 32 | if ("*".equals(parts[0])) { 33 | return new InetSocketAddress(Integer.parseInt(parts[1])); 34 | } else { 35 | InetAddress address = InetAddress.getByName(parts[0]); 36 | int port = Integer.parseInt(parts[1]); 37 | return new InetSocketAddress(address, port); 38 | } 39 | } 40 | catch (Exception e) { 41 | throw new TransformationException(e); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/database/dao/PatchListDAO.java: -------------------------------------------------------------------------------- 1 | package koserver.login.database.dao; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import koserver.common.database.dao.AbstractDAO; 8 | import koserver.login.database.entity.PatchEntity; 9 | import koserver.login.services.DatabaseService; 10 | 11 | import org.hibernate.Session; 12 | import org.hibernate.Transaction; 13 | 14 | public class PatchListDAO extends AbstractDAO { 15 | 16 | @Override 17 | public void create(final PatchEntity entity) { 18 | throw new RuntimeException("Can't create a patch !"); 19 | } 20 | 21 | @Override 22 | public PatchEntity read(final Integer id) { 23 | PatchEntity patchList = null; 24 | 25 | final Transaction transaction = session.beginTransaction(); 26 | 27 | patchList = (PatchEntity) session.get(PatchEntity.class, id); 28 | 29 | transaction.commit(); 30 | 31 | return patchList; 32 | } 33 | 34 | public List readAll() { 35 | final List patchsEntities = new ArrayList(); 36 | 37 | session.beginTransaction(); 38 | @SuppressWarnings("unchecked") 39 | final Collection patchs = session.createQuery("FROM PatchEntity").list(); 40 | if (patchs != null) { 41 | patchsEntities.addAll(patchsEntities); 42 | } 43 | session.clear(); 44 | session.getTransaction().commit(); 45 | 46 | return patchsEntities; 47 | } 48 | 49 | @Override 50 | public void update(final PatchEntity entity) { 51 | throw new RuntimeException("Can't update a patch !"); 52 | } 53 | 54 | @Override 55 | public void delete(final PatchEntity entity) { 56 | throw new RuntimeException("Can't delete a patch !"); 57 | } 58 | 59 | @Override 60 | protected Session getSession() { 61 | return DatabaseService.getInstance().getSessionFactory().openSession(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/database/dao/ServerListDAO.java: -------------------------------------------------------------------------------- 1 | package koserver.login.database.dao; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import koserver.common.database.dao.AbstractDAO; 8 | import koserver.login.database.entity.ServerEntity; 9 | import koserver.login.services.DatabaseService; 10 | 11 | import org.hibernate.Session; 12 | import org.hibernate.Transaction; 13 | 14 | public class ServerListDAO extends AbstractDAO { 15 | 16 | @Override 17 | public void create(final ServerEntity entity) { 18 | throw new RuntimeException("Can't create a server !"); 19 | } 20 | 21 | @Override 22 | public ServerEntity read(final Integer id) { 23 | ServerEntity serverList = null; 24 | 25 | final Transaction transaction = session.beginTransaction(); 26 | 27 | serverList = (ServerEntity) session.get(ServerEntity.class, id); 28 | 29 | transaction.commit(); 30 | 31 | return serverList; 32 | } 33 | 34 | public List readAll() { 35 | final List serverEntities = new ArrayList(); 36 | 37 | session.beginTransaction(); 38 | @SuppressWarnings("unchecked") 39 | final Collection servers = session.createQuery("FROM ServerEntity").list(); 40 | if (servers != null) { 41 | serverEntities.addAll(servers); 42 | } 43 | session.clear(); 44 | session.getTransaction().commit(); 45 | 46 | return serverEntities; 47 | } 48 | 49 | @Override 50 | public void update(final ServerEntity entity) { 51 | throw new RuntimeException("Can't update a server !"); 52 | } 53 | 54 | @Override 55 | public void delete(final ServerEntity entity) { 56 | throw new RuntimeException("Can't delete a server !"); 57 | } 58 | 59 | @Override 60 | protected Session getSession() { 61 | return DatabaseService.getInstance().getSessionFactory().openSession(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/database/entity/AbstractDatabaseEntity.java: -------------------------------------------------------------------------------- 1 | package koserver.common.database.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.GenerationType; 8 | import javax.persistence.Id; 9 | import javax.persistence.MappedSuperclass; 10 | 11 | import koserver.common.entity.AbstractEntity; 12 | 13 | @MappedSuperclass 14 | public abstract class AbstractDatabaseEntity extends AbstractEntity implements Serializable { 15 | 16 | private static final long serialVersionUID = -779623826754385140L; 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | @Column(name = "id", unique = true, updatable = false, nullable = false) 21 | protected Integer id; 22 | 23 | public AbstractDatabaseEntity(Integer id) { 24 | this.id = id; 25 | } 26 | 27 | public AbstractDatabaseEntity() {} 28 | 29 | public final Integer getId() { 30 | return id; 31 | } 32 | 33 | public final void setId(Integer id) { 34 | this.id = id; 35 | } 36 | 37 | @Override 38 | public int hashCode() { 39 | final int prime = 31; 40 | int result = 1; 41 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 42 | return result; 43 | } 44 | 45 | @Override 46 | public boolean equals(Object obj) { 47 | if (this == obj) { 48 | return true; 49 | } 50 | if (obj == null) { 51 | return false; 52 | } 53 | if (!(obj instanceof AbstractDatabaseEntity)) { 54 | return false; 55 | } 56 | AbstractDatabaseEntity other = (AbstractDatabaseEntity) obj; 57 | if (id == null) { 58 | if (other.id != null) { 59 | return false; 60 | } 61 | } 62 | else if (!id.equals(other.id)) { 63 | return false; 64 | } 65 | return true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/PacketListener.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | 7 | import koserver.common.utils.ArrayUtils; 8 | 9 | public class PacketListener { 10 | 11 | private BufferedInputStream bin; 12 | private InputStream in; 13 | 14 | private byte[] header; 15 | private byte[] length; 16 | private byte[] data; 17 | private byte[] tail; 18 | 19 | public PacketListener(InputStream in) { 20 | this.in = in; 21 | this.bin = new BufferedInputStream(this.in); 22 | } 23 | 24 | public Packet waitForPacket() throws IOException, Exception { 25 | int bytesReaded = 0; 26 | 27 | header = new byte[2]; 28 | bytesReaded = bin.read(header); 29 | 30 | if (bytesReaded == 0 || bytesReaded == -1) 31 | throw new IOException("Connection closed."); 32 | 33 | if (ArrayUtils.byteArrayToShort(header) != 0x55AA) { 34 | long skippedBytesCount = bin.skip(bin.available()); 35 | throw new Exception("Packet without header or invalid, skipping " + skippedBytesCount + " bytes remaining in buffer"); 36 | } 37 | 38 | length = new byte[2]; 39 | bin.read(length); 40 | int dataLength = ArrayUtils.byteArrayToShort(length); 41 | 42 | if (dataLength > Short.MAX_VALUE) { 43 | throw new Exception("Packet maximum size excceded: " + dataLength); 44 | } 45 | 46 | data = new byte[dataLength]; 47 | int offset = 0; 48 | offset = bin.read(data, offset, data.length - offset); 49 | 50 | while (true) { 51 | if (offset >= dataLength) { 52 | break; 53 | } 54 | int readed = bin.read(data, offset, data.length - offset); 55 | offset += readed; 56 | } 57 | 58 | tail = new byte[2]; 59 | bin.read(tail); 60 | 61 | if (tail[0] != header[1] || tail[1] != header[0]) { 62 | throw new Exception("Packet without tail"); 63 | } 64 | 65 | Packet packet = new Packet(ArrayUtils.byteArrayToShort(new byte[]{data[0]}, 0)); 66 | packet.setData(data); 67 | 68 | return packet; 69 | } 70 | } -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/database/entity/ServerEntity.java: -------------------------------------------------------------------------------- 1 | package koserver.login.database.entity; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.Table; 6 | 7 | import koserver.common.database.entity.AbstractDatabaseEntity; 8 | 9 | @Entity 10 | @Table(name="server") 11 | public class ServerEntity extends AbstractDatabaseEntity { 12 | 13 | private static final long serialVersionUID = -1506148037250430137L; 14 | 15 | @Column(name = "ip") 16 | private String ip; 17 | 18 | @Column(name = "category") 19 | private int category; 20 | 21 | @Column(name = "name") 22 | private String name; 23 | 24 | @Column(name = "user_count") 25 | private short userCount; 26 | 27 | @Column(name = "user_max") 28 | private short userMax; 29 | 30 | @Column(name = "user_max_free") 31 | private short userMaxFree; 32 | 33 | public String getIp() { 34 | return ip; 35 | } 36 | 37 | public void setIp(final String ip) { 38 | this.ip = ip; 39 | } 40 | 41 | public int getCategory() { 42 | return category; 43 | } 44 | 45 | public void setCategory(final int category) { 46 | this.category = category; 47 | } 48 | 49 | public String getName() { 50 | return name; 51 | } 52 | 53 | public void setName(final String name) { 54 | this.name = name; 55 | } 56 | 57 | public short getUserCount() { 58 | return userCount; 59 | } 60 | 61 | public void setUserCount(short userCount) { 62 | this.userCount = userCount; 63 | } 64 | 65 | public short getUserMax() { 66 | return userMax; 67 | } 68 | 69 | public void setUserMax(short userMax) { 70 | this.userMax = userMax; 71 | } 72 | 73 | public short getUserMaxFree() { 74 | return userMaxFree; 75 | } 76 | 77 | public void setUserMaxFree(short userMaxFree) { 78 | this.userMaxFree = userMaxFree; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/database/dao/PlayerDAO.java: -------------------------------------------------------------------------------- 1 | package koserver.game.database.dao; 2 | 3 | import koserver.common.database.dao.AbstractDAO; 4 | import koserver.game.database.entity.PlayerEntity; 5 | import koserver.game.services.DatabaseService; 6 | 7 | import org.hibernate.Query; 8 | import org.hibernate.Session; 9 | import org.hibernate.Transaction; 10 | 11 | public class PlayerDAO extends AbstractDAO { 12 | 13 | @Override 14 | public void create(final PlayerEntity entity) { 15 | final Transaction transaction = session.beginTransaction(); 16 | 17 | final Integer id = (Integer) session.save(entity); 18 | entity.setId(id); 19 | 20 | transaction.commit(); 21 | } 22 | 23 | @Override 24 | public PlayerEntity read(final Integer id) { 25 | PlayerEntity player = null; 26 | 27 | final Transaction transaction = session.beginTransaction(); 28 | 29 | player = (PlayerEntity) session.get(PlayerEntity.class, id); 30 | 31 | transaction.commit(); 32 | 33 | return player; 34 | } 35 | 36 | public PlayerEntity readByName(final String name) { 37 | PlayerEntity player = null; 38 | 39 | final Transaction transaction = session.beginTransaction(); 40 | 41 | final Query query = session.createQuery("from PlayerEntity where name = :name"); 42 | query.setString("name", name); 43 | 44 | player = (PlayerEntity) query.uniqueResult(); 45 | 46 | transaction.commit(); 47 | 48 | return player; 49 | } 50 | 51 | @Override 52 | public void update(final PlayerEntity entity) { 53 | final Transaction transaction = session.beginTransaction(); 54 | 55 | session.update(session.merge(entity)); 56 | 57 | transaction.commit(); 58 | } 59 | 60 | @Override 61 | public void delete(final PlayerEntity entity) { 62 | final Transaction transaction = session.beginTransaction(); 63 | 64 | session.delete(session.merge(entity)); 65 | 66 | transaction.commit(); 67 | } 68 | 69 | @Override 70 | protected Session getSession() { 71 | return DatabaseService.getInstance().getSessionFactory().openSession(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/services/ConfigurationService.java: -------------------------------------------------------------------------------- 1 | package koserver.login.services; 2 | 3 | import java.util.Properties; 4 | 5 | import koserver.common.config.ConfigurableProcessor; 6 | import koserver.common.services.AbstractService; 7 | import koserver.common.utils.PropertiesUtils; 8 | import koserver.login.configuration.AccountConfig; 9 | import koserver.login.configuration.NetworkConfig; 10 | import koserver.login.configuration.LoginConfig; 11 | 12 | import org.apache.log4j.Logger; 13 | import org.apache.log4j.PropertyConfigurator; 14 | 15 | public class ConfigurationService extends AbstractService { 16 | 17 | private static Logger log = Logger.getLogger(ConfigurationService.class.getName()); 18 | 19 | private ConfigurationService() { 20 | } 21 | 22 | @Override 23 | public void onInit() { 24 | PropertyConfigurator.configure(System.getProperty("user.dir") + System.getProperty("file.separator") + "config" + System.getProperty("file.separator") + "log4j.properties"); 25 | 26 | try { 27 | final Properties[] properties = PropertiesUtils.loadAllFromDirectory("config"); 28 | ConfigurableProcessor.process(NetworkConfig.class, properties); 29 | ConfigurableProcessor.process(LoginConfig.class, properties); 30 | ConfigurableProcessor.process(AccountConfig.class, properties); 31 | } 32 | catch (final Exception e) { 33 | log.fatal("Can't load loginserver configurations", e); 34 | throw new Error("Can't load loginserver configurations", e); 35 | } 36 | log.info("ConfigurationService started"); 37 | } 38 | 39 | @Override 40 | public void onDestroy() { 41 | log.info("ConfigurationService stopped"); 42 | } 43 | 44 | public static ConfigurationService getInstance() { 45 | return SingletonHolder.instance; 46 | } 47 | 48 | private static class SingletonHolder { 49 | protected static final ConfigurationService instance = new ConfigurationService(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/network/PacketWriter.java: -------------------------------------------------------------------------------- 1 | package koserver.game.network; 2 | 3 | import java.io.BufferedOutputStream; 4 | import java.io.IOException; 5 | 6 | import org.apache.log4j.Logger; 7 | 8 | import koserver.common.network.Packet; 9 | import koserver.common.utils.ArrayUtils; 10 | import koserver.game.services.AccountService; 11 | 12 | public class PacketWriter { 13 | 14 | private static Logger log = Logger.getLogger(PacketWriter.class.getName()); 15 | private AccountService clientService; 16 | private BufferedOutputStream bout; 17 | 18 | public PacketWriter(AccountService clientService) throws IOException { 19 | this.clientService = clientService; 20 | this.bout = new BufferedOutputStream(clientService.getSocket().getOutputStream()); 21 | } 22 | 23 | public boolean sendPacket(Packet packet) { 24 | try { 25 | byte[] header = new byte[] { -86, 85 }; 26 | byte[] data = packet.getData(); 27 | byte[] opcodeBytes = new byte[] { (byte) packet.getOpcode() }; 28 | byte[] tail = new byte[] { 85, -86 }; 29 | 30 | packet.setData(opcodeBytes); 31 | packet.appendData(data); 32 | data = packet.getData(); 33 | 34 | if (clientService.isCryptoEnabled()) { 35 | packet.setData(ArrayUtils.shortToByteArray((short) 0x1EFC)); 36 | packet.appendShort(clientService.getPacketSecuenceId()); 37 | packet.appendInt8(0); 38 | packet.appendData(data); 39 | 40 | data = clientService.getCryptor().EncryptionWithCRC32(packet.getData()); 41 | if (data != null) { 42 | packet.setData(data); 43 | } 44 | } 45 | 46 | byte[] length = ArrayUtils.shortToByteArray((short) (data.length)); 47 | 48 | packet.setData(header); 49 | packet.appendData(length); 50 | packet.appendData(data); 51 | packet.appendData(tail); 52 | 53 | byte[] completePacketData = packet.getData(); 54 | 55 | bout.write(completePacketData); 56 | bout.flush(); 57 | } catch (IOException e) { 58 | log.warn("Failed to send packet: " + e.getMessage()); 59 | return false; 60 | } 61 | 62 | return true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/services/ConfigurationService.java: -------------------------------------------------------------------------------- 1 | package koserver.game.services; 2 | 3 | import java.util.Properties; 4 | 5 | import koserver.common.config.ConfigurableProcessor; 6 | import koserver.common.services.AbstractService; 7 | import koserver.common.utils.PropertiesUtils; 8 | import koserver.game.configuration.GameConfig; 9 | import koserver.game.configuration.GlobalConfig; 10 | import koserver.game.configuration.NetworkConfig; 11 | import koserver.game.configuration.PlayerConfig; 12 | 13 | import org.apache.log4j.Logger; 14 | import org.apache.log4j.PropertyConfigurator; 15 | 16 | public class ConfigurationService extends AbstractService { 17 | 18 | private static Logger log = Logger.getLogger(ConfigurationService.class.getName()); 19 | 20 | private ConfigurationService() { 21 | } 22 | 23 | @Override 24 | public void onInit() { 25 | PropertyConfigurator.configure(System.getProperty("user.dir") + System.getProperty("file.separator") + "config" + System.getProperty("file.separator") + "log4j.properties"); 26 | 27 | try { 28 | final Properties[] properties = PropertiesUtils.loadAllFromDirectory("config"); 29 | ConfigurableProcessor.process(NetworkConfig.class, properties); 30 | ConfigurableProcessor.process(GameConfig.class, properties); 31 | ConfigurableProcessor.process(PlayerConfig.class, properties); 32 | ConfigurableProcessor.process(GlobalConfig.class, properties); 33 | } catch (final Exception e) { 34 | log.fatal("Can't load gameserver configurations", e); 35 | throw new Error("Can't load gameserver configurations", e); 36 | } 37 | log.info("ConfigurationService started"); 38 | } 39 | 40 | @Override 41 | public void onDestroy() { 42 | log.info("ConfigurationService stopped"); 43 | } 44 | 45 | public static ConfigurationService getInstance() { 46 | return SingletonHolder.instance; 47 | } 48 | 49 | private static class SingletonHolder { 50 | protected static final ConfigurationService instance = new ConfigurationService(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/network/PacketWriter.java: -------------------------------------------------------------------------------- 1 | package koserver.login.network; 2 | 3 | import java.io.BufferedOutputStream; 4 | import java.io.IOException; 5 | 6 | import org.apache.log4j.Logger; 7 | 8 | import koserver.common.network.Packet; 9 | import koserver.common.utils.ArrayUtils; 10 | import koserver.login.services.AccountService; 11 | 12 | public class PacketWriter { 13 | 14 | private static Logger log = Logger.getLogger(PacketWriter.class.getName()); 15 | private AccountService clientService; 16 | private BufferedOutputStream bout; 17 | 18 | public PacketWriter(AccountService clientService) throws IOException { 19 | this.clientService = clientService; 20 | this.bout = new BufferedOutputStream(clientService.getSocket().getOutputStream()); 21 | } 22 | 23 | public boolean sendPacket(Packet packet) { 24 | try { 25 | byte[] header = new byte[] { -86, 85 }; 26 | byte[] data = packet.getData(); 27 | byte[] opcodeBytes = new byte[] { (byte) packet.getOpcode() }; 28 | byte[] tail = new byte[] { 85, -86 }; 29 | 30 | packet.setData(opcodeBytes); 31 | packet.appendData(data); 32 | data = packet.getData(); 33 | 34 | if (clientService.isCryptoEnabled()) { 35 | packet.setData(ArrayUtils.shortToByteArray((short) 0x1EFC)); 36 | packet.appendShort(clientService.getPacketSecuenceId()); 37 | packet.appendInt8(0); 38 | packet.appendData(data); 39 | 40 | data = clientService.getCryptor().EncryptionWithCRC32(packet.getData()); 41 | if (data != null) { 42 | packet.setData(data); 43 | } 44 | } 45 | 46 | byte[] length = ArrayUtils.shortToByteArray((short) (data.length)); 47 | 48 | packet.setData(header); 49 | packet.appendData(length); 50 | packet.appendData(data); 51 | packet.appendData(tail); 52 | 53 | byte[] completePacketData = packet.getData(); 54 | 55 | bout.write(completePacketData); 56 | bout.flush(); 57 | } catch (IOException e) { 58 | log.warn("Failed to send packet: " + e.getMessage()); 59 | return false; 60 | } 61 | 62 | return true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/database/dao/AccountDAO.java: -------------------------------------------------------------------------------- 1 | package koserver.game.database.dao; 2 | 3 | import koserver.common.database.dao.AbstractDAO; 4 | import koserver.game.database.entity.AccountEntity; 5 | import koserver.game.services.DatabaseService; 6 | 7 | import org.hibernate.Query; 8 | import org.hibernate.Session; 9 | import org.hibernate.Transaction; 10 | 11 | public class AccountDAO extends AbstractDAO { 12 | 13 | @Override 14 | public void create(final AccountEntity entity) { 15 | final Transaction transaction = session.beginTransaction(); 16 | 17 | final Integer id = (Integer) session.save(entity); 18 | entity.setId(id); 19 | 20 | transaction.commit(); 21 | } 22 | 23 | @Override 24 | public AccountEntity read(final Integer id) { 25 | AccountEntity account = null; 26 | 27 | final Transaction transaction = session.beginTransaction(); 28 | 29 | account = (AccountEntity) session.get(AccountEntity.class, id); 30 | 31 | transaction.commit(); 32 | 33 | return account; 34 | } 35 | 36 | public AccountEntity readByLogin(final String login) { 37 | AccountEntity account = null; 38 | 39 | final Transaction transaction = session.beginTransaction(); 40 | 41 | final Query query = session.createQuery("from AccountEntity where login = :login"); 42 | query.setString("login", login); 43 | 44 | account = (AccountEntity) query.uniqueResult(); 45 | 46 | transaction.commit(); 47 | 48 | return account; 49 | } 50 | 51 | @Override 52 | public void update(final AccountEntity entity) { 53 | final Transaction transaction = session.beginTransaction(); 54 | 55 | session.update(session.merge(entity)); 56 | 57 | transaction.commit(); 58 | } 59 | 60 | @Override 61 | public void delete(final AccountEntity entity) { 62 | final Transaction transaction = session.beginTransaction(); 63 | 64 | session.delete(session.merge(entity)); 65 | 66 | transaction.commit(); 67 | } 68 | 69 | @Override 70 | protected Session getSession() { 71 | return DatabaseService.getInstance().getSessionFactory().openSession(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/enums/GameSystem.java: -------------------------------------------------------------------------------- 1 | package koserver.game.enums; 2 | 3 | public class GameSystem { 4 | 5 | public static final int KARUS_ID = 1; 6 | public static final int ELMORAD_ID = 2; 7 | 8 | public static final int MAX_ACCOUNT_CHARACTER = 3; // Maximun characters per account 9 | 10 | // Item slot define 11 | public static final short RIGHTEAR = 0; 12 | public static final short HEAD = 1; 13 | public static final short LEFTEAR = 2; 14 | public static final short NECK = 3; 15 | public static final short BREAST = 4; 16 | public static final short SHOULDER = 5; 17 | public static final short RIGHTHAND = 6; 18 | public static final short WAIST = 7; 19 | public static final short LEFTHAND = 8; 20 | public static final short RIGHTRING = 9; 21 | public static final short LEG = 10; 22 | public static final short LEFTRING = 11; 23 | public static final short GLOVE = 12; 24 | public static final short FOOT = 13; 25 | public static final short RESERVED = 14; 26 | 27 | // Item slots size define 28 | public static final short EQUIPED_SLOTS = 14; // Equiped item slots 29 | public static final short INVENTORY_SLOTS = 28; // Inventory slots 30 | public static final short COSPRE_SLOTS = 5; // Costume premium slots (1 Wing, 2 Gloves, 1 Helmet, 1 Armor) 31 | public static final short MAGICBAG_COUNT = 2; // Magic bag count 32 | public static final short MAGICBAG_SLOTS = 12; // Magic bag slots 33 | 34 | public static final short MAGICBAG_TOTAL_SLOTS = MAGICBAG_COUNT * MAGICBAG_SLOTS; 35 | public static final short INVENTORY_AREA = EQUIPED_SLOTS; 36 | public static final short COSPRE_AREA = INVENTORY_AREA + INVENTORY_SLOTS; 37 | public static final short MAGICBAGS_AREA = COSPRE_AREA + COSPRE_SLOTS; 38 | public static final short MAGICBAG1_AREA = MAGICBAGS_AREA + MAGICBAG_COUNT; 39 | public static final short MAGICBAG2_AREA = MAGICBAG1_AREA + MAGICBAG_SLOTS; 40 | public static final short INVENTARY_TOTAL_SLOTS = MAGICBAG2_AREA + MAGICBAG_SLOTS; 41 | } 42 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/services/DatabaseService.java: -------------------------------------------------------------------------------- 1 | package koserver.login.services; 2 | 3 | import java.io.File; 4 | 5 | import koserver.common.services.AbstractService; 6 | import koserver.login.database.entity.AccountEntity; 7 | import koserver.login.database.entity.PatchEntity; 8 | import koserver.login.database.entity.ServerEntity; 9 | 10 | import org.apache.log4j.Logger; 11 | import org.hibernate.SessionFactory; 12 | import org.hibernate.cfg.AnnotationConfiguration; 13 | 14 | @SuppressWarnings("deprecation") 15 | public class DatabaseService extends AbstractService { 16 | 17 | private static Logger log = Logger.getLogger(DatabaseService.class.getName()); 18 | 19 | private AnnotationConfiguration annotationConfiguration; 20 | private SessionFactory sessionFactory; 21 | 22 | private DatabaseService() { 23 | try { 24 | this.annotationConfiguration = new AnnotationConfiguration().configure(new File("config/hibernate.cfg.xml")).addPackage("koserver.login.database.entity"); 25 | 26 | this.annotationConfiguration 27 | .addAnnotatedClass(ServerEntity.class) 28 | .addAnnotatedClass(PatchEntity.class) 29 | .addAnnotatedClass(AccountEntity.class) 30 | ; 31 | 32 | this.sessionFactory = this.annotationConfiguration.buildSessionFactory(); 33 | } 34 | catch (final Throwable ex) { 35 | System.err.println("Initial SessionFactory creation failed." + ex); 36 | throw new ExceptionInInitializerError(ex); 37 | } 38 | } 39 | 40 | @Override 41 | public void onInit() { 42 | log.info("DatabaseService started"); 43 | } 44 | 45 | @Override 46 | public void onDestroy() { 47 | } 48 | 49 | public SessionFactory getSessionFactory() { 50 | return this.sessionFactory; 51 | } 52 | 53 | public static DatabaseService getInstance() { 54 | return SingletonHolder.instance; 55 | } 56 | 57 | private static class SingletonHolder { 58 | protected static final DatabaseService instance = new DatabaseService(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/delegate/AccountDelegate.java: -------------------------------------------------------------------------------- 1 | package koserver.game.delegate; 2 | 3 | import koserver.common.database.dao.DAOManager; 4 | import koserver.common.mapper.MapperManager; 5 | import koserver.game.database.dao.AccountDAO; 6 | import koserver.game.database.entity.AccountEntity; 7 | import koserver.game.mapper.database.AccountMapper; 8 | import koserver.game.models.account.Account; 9 | 10 | public class AccountDelegate { 11 | 12 | public static void createAccountEntity(final AccountEntity entity) { 13 | DAOManager.getDAO(AccountDAO.class).create(entity); 14 | } 15 | 16 | public static AccountEntity readAccountEntityById(final Integer id) { 17 | return DAOManager.getDAO(AccountDAO.class).read(id); 18 | } 19 | 20 | public static AccountEntity readAccountEntityByLogin(final String login) { 21 | return DAOManager.getDAO(AccountDAO.class).readByLogin(login); 22 | } 23 | 24 | public static void updateAccountEntity(final AccountEntity entity) { 25 | DAOManager.getDAO(AccountDAO.class).update(entity); 26 | } 27 | 28 | public static void createAccountModel(final Account model) { 29 | final AccountEntity accountEntity = MapperManager.getDatabaseMapper(AccountMapper.class).map(model); 30 | AccountDelegate.createAccountEntity(accountEntity); 31 | model.setId(accountEntity.getId()); 32 | } 33 | 34 | public static Account readAccountModelById(final Integer id) { 35 | Account player = null; 36 | final AccountEntity accountEntity = AccountDelegate.readAccountEntityById(id); 37 | if (accountEntity != null) { 38 | player = MapperManager.getDatabaseMapper(AccountMapper.class).map(accountEntity); 39 | } 40 | return player; 41 | } 42 | 43 | public static Account readAccountModelByLogin(final String login) { 44 | Account account = null; 45 | final AccountEntity accountEntity = AccountDelegate.readAccountEntityByLogin(login); 46 | if (accountEntity != null) { 47 | account = MapperManager.getDatabaseMapper(AccountMapper.class).map(accountEntity); 48 | } 49 | return account; 50 | } 51 | 52 | public static void updateAccountModel(final Account model) { 53 | final AccountEntity accountEntity = MapperManager.getDatabaseMapper(AccountMapper.class).map(model); 54 | AccountDelegate.updateAccountEntity(accountEntity); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/database/dao/AccountDAO.java: -------------------------------------------------------------------------------- 1 | package koserver.login.database.dao; 2 | 3 | import koserver.common.database.dao.AbstractDAO; 4 | import koserver.login.database.entity.AccountEntity; 5 | import koserver.login.services.DatabaseService; 6 | 7 | import org.hibernate.Query; 8 | import org.hibernate.Session; 9 | import org.hibernate.Transaction; 10 | 11 | public class AccountDAO extends AbstractDAO { 12 | 13 | @Override 14 | public void create(final AccountEntity entity) { 15 | final Transaction transaction = session.beginTransaction(); 16 | 17 | final Integer id = (Integer) session.save(entity); 18 | entity.setId(id); 19 | 20 | transaction.commit(); 21 | } 22 | 23 | @Override 24 | public AccountEntity read(final Integer id) { 25 | AccountEntity account = null; 26 | 27 | final Transaction transaction = session.beginTransaction(); 28 | 29 | account = (AccountEntity) session.get(AccountEntity.class, id); 30 | 31 | transaction.commit(); 32 | 33 | return account; 34 | } 35 | 36 | public AccountEntity readByLogin(final String login) { 37 | AccountEntity account = null; 38 | 39 | final Transaction transaction = session.beginTransaction(); 40 | 41 | final Query query = session.createQuery("from AccountEntity where login = :login"); 42 | query.setString("login", login); 43 | 44 | account = (AccountEntity) query.uniqueResult(); 45 | 46 | transaction.commit(); 47 | 48 | return account; 49 | } 50 | 51 | @Override 52 | public void update(final AccountEntity entity) { 53 | final Transaction transaction = session.beginTransaction(); 54 | 55 | session.update(session.merge(entity)); 56 | 57 | transaction.commit(); 58 | } 59 | 60 | @Override 61 | public void delete(final AccountEntity entity) { 62 | final Transaction transaction = session.beginTransaction(); 63 | 64 | session.delete(session.merge(entity)); 65 | 66 | transaction.commit(); 67 | } 68 | 69 | @Override 70 | protected Session getSession() { 71 | return DatabaseService.getInstance().getSessionFactory().openSession(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/utils/ByteArrayReader.java: -------------------------------------------------------------------------------- 1 | package koserver.common.utils; 2 | 3 | public class ByteArrayReader { 4 | private byte[] data; 5 | private int position; 6 | 7 | public ByteArrayReader() { 8 | 9 | } 10 | 11 | public ByteArrayReader(byte[] data) { 12 | this.data = data; 13 | } 14 | 15 | public void setData(byte[] data) { 16 | this.data = data; 17 | } 18 | 19 | public byte[] getData() { 20 | return data; 21 | } 22 | 23 | public void appendData(byte[] data) { 24 | byte[] newData = new byte[this.data.length + data.length]; 25 | System.arraycopy(this.data, 0, newData, 0, this.data.length); 26 | System.arraycopy(data, 0, newData, this.data.length, data.length); 27 | this.data = newData; 28 | } 29 | 30 | public void appendByteArray(byte[] objectData) { 31 | appendData(ArrayUtils.intToByteArray(objectData.length)); 32 | appendData(objectData); 33 | } 34 | 35 | public byte[] getByteArray() { 36 | try { 37 | int length = ArrayUtils.byteArrayToInt(data, position, position + 4); 38 | position += 4; 39 | byte[] byteArray = ArrayUtils.arraySubset(data, position, position + length); 40 | position += length; 41 | 42 | return byteArray; 43 | } catch (Exception e) { 44 | return null; 45 | } 46 | } 47 | 48 | public void appendString(String data) { 49 | appendData(ArrayUtils.shortToByteArray((short) data.length())); 50 | appendData(data.getBytes()); 51 | } 52 | 53 | public String getString() { 54 | try { 55 | short length = ArrayUtils.byteArrayToShort(data, position, position + 2); 56 | position += 2; 57 | String value = ArrayUtils.hexToString(ArrayUtils.byteArrayToHex(data, position, position + length)); 58 | position += length; 59 | 60 | return value; 61 | } catch (Exception ex) { 62 | return ""; 63 | } 64 | } 65 | 66 | public void appendShort(short data) { 67 | appendData(ArrayUtils.shortToByteArray(data)); 68 | } 69 | 70 | public short getInt8() { 71 | try { 72 | short value = ArrayUtils.byteArrayToShort(data, position, position + 1); 73 | position += 1; 74 | return value; 75 | } catch (Exception ex) { 76 | return -1; 77 | } 78 | } 79 | 80 | public short getShort() { 81 | try { 82 | short value = ArrayUtils.byteArrayToShort(data, position, position + 2); 83 | position += 2; 84 | return value; 85 | } catch (Exception ex) { 86 | return -1; 87 | } 88 | } 89 | 90 | public int getInt() { 91 | try { 92 | int value = ArrayUtils.byteArrayToInt(data, position, position + 4); 93 | position += 4; 94 | return value; 95 | } catch (Exception ex) { 96 | return -1; 97 | } 98 | } 99 | 100 | public void appendInt(int data) { 101 | appendData(ArrayUtils.intToByteArray(data)); 102 | } 103 | 104 | public void appendInt8(int data) { 105 | appendData(new byte[] { (byte) data }); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /koserver-game/config/hibernate-configuration-3.0.dtd: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /koserver-login/config/hibernate-configuration-3.0.dtd: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/mapper/database/AccountMapper.java: -------------------------------------------------------------------------------- 1 | package koserver.game.mapper.database; 2 | 3 | import java.util.List; 4 | import java.util.Set; 5 | 6 | import javolution.util.FastList; 7 | import javolution.util.FastSet; 8 | import koserver.common.entity.AbstractEntity; 9 | import koserver.common.enums.AccountAuthority; 10 | import koserver.common.mapper.MapperManager; 11 | import koserver.common.mapper.database.DatabaseMapper; 12 | import koserver.common.models.AbstractModel; 13 | import koserver.game.database.entity.AccountEntity; 14 | import koserver.game.database.entity.PlayerEntity; 15 | import koserver.game.models.account.Account; 16 | import koserver.game.models.player.Player; 17 | 18 | public class AccountMapper extends DatabaseMapper { 19 | 20 | @Override 21 | public AccountEntity map(final Account model, final AbstractEntity linkedEntity) { 22 | final AccountEntity accountEntity = new AccountEntity(model.getId()); 23 | 24 | // DIRECT 25 | accountEntity.setLogin(model.getLogin()); 26 | accountEntity.setPassword(model.getPassword()); 27 | accountEntity.setNation(model.getNation()); 28 | accountEntity.setAuthority(model.getAuthority().getValue()); 29 | accountEntity.setAccess(model.getAccess()); 30 | accountEntity.setCreation(model.getCreation()); 31 | 32 | // PLAYER 33 | final Set players = new FastSet<>(); 34 | for (final Player player : model.getPlayers()) { 35 | if (linkedEntity instanceof PlayerEntity && MapperManager.getDatabaseMapper(PlayerMapper.class).equals(player, (PlayerEntity) linkedEntity)) { 36 | players.add((PlayerEntity) linkedEntity); 37 | } else { 38 | players.add(MapperManager.getDatabaseMapper(PlayerMapper.class).map(player, accountEntity)); 39 | } 40 | } 41 | accountEntity.setPlayers(players); 42 | 43 | return accountEntity; 44 | } 45 | 46 | @Override 47 | public Account map(final AccountEntity model, final AbstractModel linkedModel) { 48 | final Account account = new Account(model.getId()); 49 | 50 | // DIRECT 51 | account.setLogin(model.getLogin()); 52 | account.setPassword(model.getPassword()); 53 | account.setNation(model.getNation()); 54 | account.setAuthority(AccountAuthority.from(model.getAuthority())); 55 | account.setAccess(model.getAccess()); 56 | account.setCreation(model.getCreation()); 57 | 58 | // PLAYER 59 | final List players = new FastList(); 60 | for (final PlayerEntity playerEntity : model.getPlayers()) { 61 | if (linkedModel instanceof Player && MapperManager.getDatabaseMapper(PlayerMapper.class).equals((Player) linkedModel, playerEntity)) { 62 | players.add((Player) linkedModel); 63 | } else { 64 | players.add(MapperManager.getDatabaseMapper(PlayerMapper.class).map(playerEntity, account)); 65 | } 66 | 67 | } 68 | account.setPlayers(players); 69 | 70 | return account; 71 | } 72 | 73 | @Override 74 | public boolean equals(final Account model, final AccountEntity entity) { 75 | return model.getLogin().equals(entity.getLogin()); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/Packet.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network; 2 | 3 | import koserver.common.utils.ArrayUtils; 4 | 5 | public class Packet { 6 | 7 | private int opcode; 8 | private byte[] data; 9 | private int position; 10 | 11 | public Packet(int opcode) { 12 | this.opcode = opcode; 13 | data = new byte[0]; 14 | position = 0; 15 | } 16 | 17 | public void setData(byte[] data) { 18 | this.data = data; 19 | } 20 | 21 | public byte[] getData() { 22 | return data; 23 | } 24 | 25 | public int getOpcode() { 26 | return opcode; 27 | } 28 | 29 | public void appendData(byte[] data) { 30 | byte[] newData = new byte[this.data.length + data.length]; 31 | System.arraycopy(this.data, 0, newData, 0, this.data.length); 32 | System.arraycopy(data, 0, newData, this.data.length, data.length); 33 | this.data = newData; 34 | } 35 | 36 | public void appendByteArray(byte[] objectData) { 37 | appendData(ArrayUtils.intToByteArray(objectData.length)); 38 | appendData(objectData); 39 | } 40 | 41 | public byte[] getByteArray() { 42 | try { 43 | int length = ArrayUtils.byteArrayToInt(data, position, position + 4); 44 | position += 4; 45 | byte[] byteArray = ArrayUtils.arraySubset(data, position, position + length); 46 | position += length; 47 | 48 | return byteArray; 49 | } catch (Exception e) { 50 | return null; 51 | } 52 | } 53 | 54 | public void appendString(String data) { 55 | appendData(ArrayUtils.shortToByteArray((short) data.length())); 56 | appendData(data.getBytes()); 57 | } 58 | 59 | public String getString() { 60 | try { 61 | short length = ArrayUtils.byteArrayToShort(data, position, position + 2); 62 | position += 2; 63 | String value = ArrayUtils.hexToString(ArrayUtils.byteArrayToHex(data, position, position + length)); 64 | position += length; 65 | 66 | return value; 67 | } catch (Exception ex) { 68 | return ""; 69 | } 70 | } 71 | 72 | public void appendShort(short data) { 73 | appendData(ArrayUtils.shortToByteArray(data)); 74 | } 75 | 76 | public short getInt8() { 77 | try { 78 | short value = ArrayUtils.byteArrayToShort(data, position, position + 1); 79 | position += 1; 80 | return value; 81 | } catch (Exception ex) { 82 | return -1; 83 | } 84 | } 85 | 86 | public short getShort() { 87 | try { 88 | short value = ArrayUtils.byteArrayToShort(data, position, position + 2); 89 | position += 2; 90 | return value; 91 | } catch (Exception ex) { 92 | return -1; 93 | } 94 | } 95 | 96 | public int getInt() { 97 | try { 98 | int value = ArrayUtils.byteArrayToInt(data, position, position + 4); 99 | position += 4; 100 | return value; 101 | } catch (Exception ex) { 102 | return -1; 103 | } 104 | } 105 | 106 | public void appendInt(int data) { 107 | appendData(ArrayUtils.intToByteArray(data)); 108 | } 109 | 110 | public void appendInt8(int data) { 111 | appendData(new byte[] { (byte) data }); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/database/entity/AccountEntity.java: -------------------------------------------------------------------------------- 1 | package koserver.login.database.entity; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.Table; 8 | 9 | import koserver.common.database.entity.AbstractDatabaseEntity; 10 | 11 | @Entity 12 | @Table(name = "account") 13 | public class AccountEntity extends AbstractDatabaseEntity { 14 | 15 | private static final long serialVersionUID = 1L; 16 | 17 | @Column(name = "login") 18 | private String login; 19 | 20 | @Column(name = "password") 21 | private String password; 22 | 23 | @Column(name = "nation") 24 | private int nation; 25 | 26 | @Column(name = "authority") 27 | private int authority; 28 | 29 | @Column(name = "seal_password") 30 | private String sealPassword; 31 | 32 | @Column(name = "cash") 33 | private int cash; 34 | 35 | @Column(name = "birh_date") 36 | private Date birthDate; 37 | 38 | @Column(name = "email") 39 | private String email; 40 | 41 | @Column(name = "creation") 42 | private Date creation; 43 | 44 | @Column(name = "last_access") 45 | private Date access; 46 | 47 | public AccountEntity(final Integer id) { 48 | super(id); 49 | } 50 | 51 | public AccountEntity() { 52 | super(); 53 | } 54 | 55 | public String getLogin() { 56 | return login; 57 | } 58 | 59 | public void setLogin(String login) { 60 | this.login = login; 61 | } 62 | 63 | public String getPassword() { 64 | return password; 65 | } 66 | 67 | public void setPassword(String password) { 68 | this.password = password; 69 | } 70 | 71 | public int getNation() { 72 | return nation; 73 | } 74 | 75 | public void setNation(int nation) { 76 | this.nation = nation; 77 | } 78 | 79 | public int getAuthority() { 80 | return authority; 81 | } 82 | 83 | public void setAuthority(int authority) { 84 | this.authority = authority; 85 | } 86 | 87 | public String getSealPassword() { 88 | return sealPassword; 89 | } 90 | 91 | public void setSealPassword(String sealPassword) { 92 | this.sealPassword = sealPassword; 93 | } 94 | 95 | public int getCash() { 96 | return cash; 97 | } 98 | 99 | public void setCash(int cash) { 100 | this.cash = cash; 101 | } 102 | 103 | public Date getBirthDate() { 104 | return birthDate; 105 | } 106 | 107 | public void setBirthDate(Date birthDate) { 108 | this.birthDate = birthDate; 109 | } 110 | 111 | public String getEmail() { 112 | return email; 113 | } 114 | 115 | public void setEmail(String email) { 116 | this.email = email; 117 | } 118 | 119 | public Date getCreation() { 120 | return creation; 121 | } 122 | 123 | public void setCreation(Date creation) { 124 | this.creation = creation; 125 | } 126 | 127 | public Date getAccess() { 128 | return access; 129 | } 130 | 131 | public void setAccess(Date access) { 132 | this.access = access; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/Property.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.FIELD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface Property { 11 | /** 12 | * This string shows to {@link com.aionemu.commons.configuration.ConfigurableProcessor} that init value of the 13 | * object should not be overriden. 14 | */ 15 | public static final String DEFAULT_VALUE = "DO_NOT_OVERWRITE_INITIALIAZION_VALUE"; 16 | 17 | /** 18 | * Property name in configuration 19 | * 20 | * @return name of the property that will be used 21 | */ 22 | public String key(); 23 | 24 | /** 25 | * PropertyTransformer to use.
26 | * List of automaticly transformed types:
27 | *
    28 | *
  • {@link Boolean} and boolean by {@link com.aionemu.commons.configuration.transformers.BooleanTransformer}
  • 29 | *
  • {@link Byte} and byte by {@link com.aionemu.commons.configuration.transformers.ByteTransformer}
  • 30 | *
  • {@link Character} and char by {@link com.aionemu.commons.configuration.transformers.CharTransformer}
  • 31 | *
  • {@link Short} and short by {@link com.aionemu.commons.configuration.transformers.ShortTransformer}
  • 32 | *
  • {@link Integer} and int by {@link com.aionemu.commons.configuration.transformers.IntegerTransformer}
  • 33 | *
  • {@link Float} and float by {@link com.aionemu.commons.configuration.transformers.FloatTransformer}
  • 34 | *
  • {@link Long} and long by {@link com.aionemu.commons.configuration.transformers.LongTransformer}
  • 35 | *
  • {@link Double} and double by {@link com.aionemu.commons.configuration.transformers.DoubleTransformer}
  • 36 | *
  • {@link String} by {@link com.aionemu.commons.configuration.transformers.StringTransformer}
  • 37 | *
  • {@link Enum} and enum by {@link com.aionemu.commons.configuration.transformers.EnumTransformer}
  • 38 | *
  • {@link java.io.File} by {@link com.aionemu.commons.configuration.transformers.FileTransformer}
  • 39 | *
  • {@link java.net.InetSocketAddress} by 40 | * {@link com.aionemu.commons.configuration.transformers.InetSocketAddressTransformer}
  • 41 | *
  • {@link java.util.regex.Pattern} by {@link com.aionemu.commons.configuration.transformers.PatternTransformer} 42 | *
43 | *

44 | * If your value is one of this types - just leave this field empty 45 | * 46 | * @return returns class that will be used to transform value 47 | */ 48 | @SuppressWarnings("rawtypes") 49 | public Class propertyTransformer() default PropertyTransformer.class; 50 | 51 | /** 52 | * Represents default value that will be parsed if key not found. If this key equals(default) {@link #DEFAULT_VALUE} 53 | * init value of the object won't be overriden 54 | * 55 | * @return default value of the property 56 | */ 57 | public String defaultValue() default DEFAULT_VALUE; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/models/Account.java: -------------------------------------------------------------------------------- 1 | package koserver.login.models; 2 | 3 | import java.util.Date; 4 | 5 | import koserver.common.enums.AccountAuthority; 6 | import koserver.common.models.AbstractModel; 7 | import koserver.login.services.AccountService; 8 | 9 | public class Account extends AbstractModel { 10 | 11 | private String login; 12 | private String password; 13 | private AccountAuthority authority; 14 | private Date access; 15 | private Date creation; 16 | private AccountService connection; 17 | 18 | public Account(final Integer id) { 19 | super(id); 20 | } 21 | 22 | public Account() { 23 | super(null); 24 | } 25 | 26 | public String getLogin() { 27 | return login; 28 | } 29 | 30 | public void setLogin(final String login) { 31 | this.login = login; 32 | } 33 | 34 | public String getPassword() { 35 | return password; 36 | } 37 | 38 | public void setPassword(final String password) { 39 | this.password = password; 40 | } 41 | 42 | public AccountAuthority getAuthority() { 43 | return authority; 44 | } 45 | 46 | public void setAuthority(AccountAuthority authority) { 47 | this.authority = authority; 48 | } 49 | 50 | public boolean isBanned() { 51 | return authority == AccountAuthority.BANNED; 52 | } 53 | 54 | public void setBanned(final boolean banned) { 55 | authority = AccountAuthority.BANNED; 56 | } 57 | 58 | public Date getAccess() { 59 | return access; 60 | } 61 | 62 | public void setAccess(final Date access) { 63 | this.access = access; 64 | } 65 | 66 | public AccountService getConnection() { 67 | return connection; 68 | } 69 | 70 | public void setConnection(final AccountService connection) { 71 | this.connection = connection; 72 | } 73 | 74 | public Date getCreation() { 75 | return creation; 76 | } 77 | 78 | public void setCreation(Date creation) { 79 | this.creation = creation; 80 | } 81 | 82 | @Override 83 | public int hashCode() { 84 | return 0; 85 | } 86 | 87 | @Override 88 | public boolean equals(final Object obj) { 89 | if (this == obj) { 90 | return true; 91 | } 92 | if (!super.equals(obj)) { 93 | return false; 94 | } 95 | if (!(obj instanceof Account)) { 96 | return false; 97 | } 98 | final Account other = (Account) obj; 99 | if (access != other.access) { 100 | return false; 101 | } 102 | if (connection == null) { 103 | if (other.connection != null) { 104 | return false; 105 | } 106 | } 107 | else if (!connection.equals(other.connection)) { 108 | return false; 109 | } 110 | if (login == null) { 111 | if (other.login != null) { 112 | return false; 113 | } 114 | } 115 | else if (!login.equals(other.login)) { 116 | return false; 117 | } 118 | if (password == null) { 119 | if (other.password != null) { 120 | return false; 121 | } 122 | } 123 | else if (!password.equals(other.password)) { 124 | return false; 125 | } 126 | return true; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/utils/HexDump.java: -------------------------------------------------------------------------------- 1 | package koserver.common.utils; 2 | 3 | public class HexDump { 4 | private final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 5 | 6 | public static String dumpHexString(byte[] array) { 7 | return dumpHexString(array, 0, array.length); 8 | } 9 | 10 | public static String dumpHexString(byte[] array, int offset, int length) { 11 | StringBuilder result = new StringBuilder(); 12 | 13 | byte[] line = new byte[16]; 14 | int lineIndex = 0; 15 | 16 | result.append("\n0x"); 17 | result.append(toHexString(offset)); 18 | 19 | for (int i = offset; i < offset + length; i++) { 20 | if (lineIndex == 16) { 21 | result.append(" "); 22 | 23 | for (int j = 0; j < 16; j++) { 24 | if (line[j] > ' ' && line[j] < '~') { 25 | result.append(new String(line, j, 1)); 26 | } else { 27 | result.append("."); 28 | } 29 | } 30 | 31 | result.append("\n0x"); 32 | result.append(toHexString(i)); 33 | lineIndex = 0; 34 | } 35 | 36 | byte b = array[i]; 37 | result.append(" "); 38 | result.append(HEX_DIGITS[(b >>> 4) & 0x0F]); 39 | result.append(HEX_DIGITS[b & 0x0F]); 40 | 41 | line[lineIndex++] = b; 42 | } 43 | 44 | if (lineIndex != 16) { 45 | int count = (16 - lineIndex) * 3; 46 | count++; 47 | for (int i = 0; i < count; i++) { 48 | result.append(" "); 49 | } 50 | 51 | for (int i = 0; i < lineIndex; i++) { 52 | if (line[i] > ' ' && line[i] < '~') { 53 | result.append(new String(line, i, 1)); 54 | } else { 55 | result.append("."); 56 | } 57 | } 58 | } 59 | 60 | return result.toString(); 61 | } 62 | 63 | public static String toHexString(byte b) { 64 | return toHexString(toByteArray(b)); 65 | } 66 | 67 | public static String toHexString(byte[] array) { 68 | return toHexString(array, 0, array.length); 69 | } 70 | 71 | public static String toHexString(byte[] array, int offset, int length) { 72 | char[] buf = new char[length * 2]; 73 | 74 | int bufIndex = 0; 75 | for (int i = offset; i < offset + length; i++) { 76 | byte b = array[i]; 77 | buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F]; 78 | buf[bufIndex++] = HEX_DIGITS[b & 0x0F]; 79 | } 80 | 81 | return new String(buf); 82 | } 83 | 84 | public static String toHexString(int i) { 85 | return toHexString(toByteArray(i)); 86 | } 87 | 88 | public static byte[] toByteArray(byte b) { 89 | byte[] array = new byte[1]; 90 | array[0] = b; 91 | return array; 92 | } 93 | 94 | public static byte[] toByteArray(int i) { 95 | byte[] array = new byte[4]; 96 | 97 | array[3] = (byte) (i & 0xFF); 98 | array[2] = (byte) ((i >> 8) & 0xFF); 99 | array[1] = (byte) ((i >> 16) & 0xFF); 100 | array[0] = (byte) ((i >> 24) & 0xFF); 101 | 102 | return array; 103 | } 104 | 105 | private static int toByte(char c) { 106 | if (c >= '0' && c <= '9') 107 | return (c - '0'); 108 | if (c >= 'A' && c <= 'F') 109 | return (c - 'A' + 10); 110 | if (c >= 'a' && c <= 'f') 111 | return (c - 'a' + 10); 112 | 113 | throw new RuntimeException("Invalid hex char '" + c + "'"); 114 | } 115 | 116 | public static byte[] hexStringToByteArray(String hexString) { 117 | int length = hexString.length(); 118 | byte[] buffer = new byte[length / 2]; 119 | 120 | for (int i = 0; i < length; i += 2) { 121 | buffer[i / 2] = (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1))); 122 | } 123 | 124 | return buffer; 125 | } 126 | } -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/database/entity/AccountEntity.java: -------------------------------------------------------------------------------- 1 | package koserver.game.database.entity; 2 | 3 | import java.util.Date; 4 | import java.util.Set; 5 | 6 | import javax.persistence.CascadeType; 7 | import javax.persistence.Column; 8 | import javax.persistence.Entity; 9 | import javax.persistence.FetchType; 10 | import javax.persistence.OneToMany; 11 | import javax.persistence.Table; 12 | 13 | import koserver.common.database.entity.AbstractDatabaseEntity; 14 | 15 | @Entity 16 | @Table(name = "account") 17 | public class AccountEntity extends AbstractDatabaseEntity { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @Column(name = "login") 22 | private String login; 23 | 24 | @Column(name = "password") 25 | private String password; 26 | 27 | @Column(name = "nation") 28 | private int nation; 29 | 30 | @Column(name = "authority") 31 | private int authority; 32 | 33 | @Column(name = "seal_password") 34 | private String sealPassword; 35 | 36 | @Column(name = "cash") 37 | private int cash; 38 | 39 | @Column(name = "birh_date") 40 | private Date birthDate; 41 | 42 | @Column(name = "email") 43 | private String email; 44 | 45 | @Column(name = "creation") 46 | private Date creation; 47 | 48 | @Column(name = "last_access") 49 | private Date access; 50 | 51 | @OneToMany(fetch = FetchType.EAGER, mappedBy = "account", cascade = CascadeType.ALL) 52 | private Set players; 53 | 54 | public AccountEntity(final Integer id) { 55 | super(id); 56 | } 57 | 58 | public AccountEntity() { 59 | super(); 60 | } 61 | 62 | public String getLogin() { 63 | return login; 64 | } 65 | 66 | public void setLogin(String login) { 67 | this.login = login; 68 | } 69 | 70 | public String getPassword() { 71 | return password; 72 | } 73 | 74 | public void setPassword(String password) { 75 | this.password = password; 76 | } 77 | 78 | public int getNation() { 79 | return nation; 80 | } 81 | 82 | public void setNation(int nation) { 83 | this.nation = nation; 84 | } 85 | 86 | public int getAuthority() { 87 | return authority; 88 | } 89 | 90 | public void setAuthority(int authority) { 91 | this.authority = authority; 92 | } 93 | 94 | public String getSealPassword() { 95 | return sealPassword; 96 | } 97 | 98 | public void setSealPassword(String sealPassword) { 99 | this.sealPassword = sealPassword; 100 | } 101 | 102 | public int getCash() { 103 | return cash; 104 | } 105 | 106 | public void setCash(int cash) { 107 | this.cash = cash; 108 | } 109 | 110 | public Date getBirthDate() { 111 | return birthDate; 112 | } 113 | 114 | public void setBirthDate(Date birthDate) { 115 | this.birthDate = birthDate; 116 | } 117 | 118 | public String getEmail() { 119 | return email; 120 | } 121 | 122 | public void setEmail(String email) { 123 | this.email = email; 124 | } 125 | 126 | public Date getCreation() { 127 | return creation; 128 | } 129 | 130 | public void setCreation(Date creation) { 131 | this.creation = creation; 132 | } 133 | 134 | public Date getAccess() { 135 | return access; 136 | } 137 | 138 | public void setAccess(Date access) { 139 | this.access = access; 140 | } 141 | 142 | public Set getPlayers() { 143 | return players; 144 | } 145 | 146 | public void setPlayers(final Set players) { 147 | this.players = players; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/utils/PrintUtils.java: -------------------------------------------------------------------------------- 1 | package koserver.common.utils; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import org.apache.commons.lang3.ArrayUtils; 6 | import org.apache.commons.lang3.StringUtils; 7 | 8 | public class PrintUtils { 9 | 10 | public static void printSection(String sectionName) { 11 | StringBuilder sb = new StringBuilder(); 12 | sb.append("-[ "+sectionName+" ]"); 13 | 14 | while (sb.length() < 79) { 15 | sb.insert(0, "="); 16 | } 17 | 18 | System.out.println(sb.toString()); 19 | } 20 | 21 | public static byte[] hex2bytes(String string) { 22 | final String finalString = string.replaceAll("\\s+",""); 23 | byte[] bytes = new byte[finalString.length() / 2]; 24 | for (int i = 0; i < bytes.length; i++) { 25 | bytes[i] = (byte) Integer.parseInt(finalString.substring(2 * i, 2 * i + 2), 16); 26 | } 27 | return bytes; 28 | } 29 | 30 | public static String bytes2hex(byte[] bytes) { 31 | StringBuilder result = new StringBuilder(); 32 | int value; 33 | for (byte b : bytes) { 34 | value = b & 0xff; 35 | result.append(String.format("%02X", value)); 36 | } 37 | return result.toString(); 38 | } 39 | 40 | public static String reverseHex(String input) { 41 | String[] chunked = new String[input.length()/2]; 42 | 43 | int position = 0; 44 | for (int i = 0 ; i < input.length() ; i+=2) { 45 | chunked[position] = input.substring(position*2, position*2+2); 46 | position++; 47 | } 48 | 49 | ArrayUtils.reverse(chunked); 50 | return StringUtils.join(chunked); 51 | } 52 | 53 | public static String toHex(ByteBuffer data) { 54 | int position = data.position(); 55 | StringBuilder result = new StringBuilder(); 56 | int counter = 0; 57 | int b; 58 | while (data.hasRemaining()) { 59 | if (counter % 16 == 0) 60 | result.append(String.format("%04X: ", counter)); 61 | 62 | b = data.get() & 0xff; 63 | result.append(String.format("%02X ", b)); 64 | 65 | counter++; 66 | if (counter % 16 == 0) { 67 | result.append(" "); 68 | toText(data, result, 16); 69 | result.append("\n"); 70 | } 71 | } 72 | int rest = counter % 16; 73 | if (rest > 0) { 74 | for (int i = 0; i < 17 - rest; i++) { 75 | result.append(" "); 76 | } 77 | toText(data, result, rest); 78 | } 79 | data.position(position); 80 | return result.toString(); 81 | } 82 | 83 | /** 84 | * Gets last cnt read bytes from the data buffer and puts 85 | * into result buffer in special format: 86 | *

    87 | *
  • if byte represents char from partition 0x1F to 0x80 (which are normal 88 | * ascii chars) then it's put into buffer as it is
  • 89 | *
  • otherwise dot is put into buffer
  • 90 | *
91 | * 92 | * @param data 93 | * @param result 94 | * @param cnt 95 | */ 96 | private static void toText(ByteBuffer data, StringBuilder result, int cnt) { 97 | int charPos = data.position() - cnt; 98 | for (int a = 0; a < cnt; a++) { 99 | int c = data.get(charPos++); 100 | if (c > 0x1f && c < 0x80) 101 | result.append((char) c); 102 | else 103 | result.append('.'); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/delegate/PlayerDelegate.java: -------------------------------------------------------------------------------- 1 | package koserver.game.delegate; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | 5 | import org.apache.commons.beanutils.BeanUtils; 6 | 7 | import koserver.common.database.dao.DAOManager; 8 | import koserver.common.mapper.MapperManager; 9 | import koserver.game.database.dao.PlayerDAO; 10 | import koserver.game.database.entity.PlayerEntity; 11 | import koserver.game.mapper.database.PlayerMapper; 12 | import koserver.game.models.player.Player; 13 | import koserver.game.services.AccountService; 14 | 15 | public class PlayerDelegate { 16 | 17 | // ------------------------------------------------------------ 18 | // PlayerEntity 19 | // ------------------------------------------------------------ 20 | public static void createPlayerEntity(final PlayerEntity entity) { 21 | DAOManager.getDAO(PlayerDAO.class).create(entity); 22 | } 23 | 24 | public static PlayerEntity readPlayerEntityById(final Integer id) { 25 | return DAOManager.getDAO(PlayerDAO.class).read(id); 26 | } 27 | 28 | public static PlayerEntity readPlayerEntityByName(final String name) { 29 | return DAOManager.getDAO(PlayerDAO.class).readByName(name); 30 | } 31 | 32 | public static void updatePlayerEntity(final PlayerEntity entity) { 33 | DAOManager.getDAO(PlayerDAO.class).update(entity); 34 | } 35 | 36 | public static void deletePlayerEntity(final PlayerEntity entity) { 37 | DAOManager.getDAO(PlayerDAO.class).delete(entity); 38 | } 39 | 40 | // ------------------------------------------------------------ 41 | // Player 42 | // ------------------------------------------------------------ 43 | public static void createPlayerModel(final Player model) { 44 | final PlayerEntity playerEntity = MapperManager.getDatabaseMapper(PlayerMapper.class).map(model); 45 | PlayerDelegate.createPlayerEntity(playerEntity); 46 | 47 | PlayerDelegate.copy(model, MapperManager.getDatabaseMapper(PlayerMapper.class).map(playerEntity)); 48 | } 49 | 50 | public static Player readPlayerModelById(final Integer id) { 51 | Player player = null; 52 | final PlayerEntity playerEntity = PlayerDelegate.readPlayerEntityById(id); 53 | if (playerEntity != null) { 54 | player = MapperManager.getDatabaseMapper(PlayerMapper.class).map(playerEntity); 55 | } 56 | return player; 57 | } 58 | 59 | public static Player readPlayerModelByName(final String name) { 60 | Player player = null; 61 | final PlayerEntity playerEntity = PlayerDelegate.readPlayerEntityByName(name); 62 | if (playerEntity != null) { 63 | player = MapperManager.getDatabaseMapper(PlayerMapper.class).map(playerEntity); 64 | } 65 | return player; 66 | } 67 | 68 | public static void updatePlayerModel(final Player model) { 69 | final PlayerEntity playerEntity = MapperManager.getDatabaseMapper(PlayerMapper.class).map(model); 70 | PlayerDelegate.updatePlayerEntity(playerEntity); 71 | 72 | // TODO we should call each DAO for each subdata 73 | PlayerDelegate.copy(model, MapperManager.getDatabaseMapper(PlayerMapper.class).map(playerEntity)); 74 | } 75 | 76 | public static void deletePlayerModel(final Player model) { 77 | final PlayerEntity playerEntity = MapperManager.getDatabaseMapper(PlayerMapper.class).map(model); 78 | PlayerDelegate.deletePlayerEntity(playerEntity); 79 | } 80 | 81 | // ------------------------------------------------------------ 82 | // Common 83 | // ------------------------------------------------------------ 84 | private static void copy(final Player modelDest, final Player modelOrig) { 85 | final AccountService connection = modelDest.getConnection(); 86 | 87 | try { 88 | BeanUtils.copyProperties(modelDest, modelOrig); 89 | } catch (IllegalAccessException | InvocationTargetException e) { 90 | e.printStackTrace(); 91 | } 92 | 93 | modelDest.getAccount().setConnection(connection); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/mapper/MapperManager.java: -------------------------------------------------------------------------------- 1 | package koserver.common.mapper; 2 | 3 | import java.util.Map; 4 | 5 | import javolution.util.FastMap; 6 | import koserver.common.database.dao.exception.DAONotFoundException; 7 | import koserver.common.mapper.database.DatabaseMapper; 8 | import koserver.common.mapper.xml.XMLListMapper; 9 | import koserver.common.mapper.xml.XMLMapper; 10 | 11 | import org.apache.log4j.Logger; 12 | 13 | public class MapperManager { 14 | 15 | /** LOGGER */ 16 | private static Logger log = Logger.getLogger(MapperManager.class.getName()); 17 | 18 | /** Collection of registered DAOs */ 19 | private static final Map> databaseMappersMap = new FastMap<>(); 20 | private static final Map> xmlMappersMap = new FastMap<>(); 21 | private static final Map> xmlListMappersMap = new FastMap<>(); 22 | 23 | private MapperManager() { 24 | // empty 25 | } 26 | 27 | public static > T getDatabaseMapper(Class clazz) { 28 | MapperManager.ensureDatabaseMapper(clazz); 29 | 30 | @SuppressWarnings("unchecked") 31 | T result = (T) databaseMappersMap.get(clazz.getName()); 32 | 33 | if (result == null) { 34 | throw new DAONotFoundException("Mapper Not found "+clazz.getName()); 35 | } 36 | 37 | return result; 38 | } 39 | 40 | public static > T getXMLMapper(Class clazz) { 41 | MapperManager.ensureXMLMapper(clazz); 42 | 43 | @SuppressWarnings("unchecked") 44 | T result = (T) xmlMappersMap.get(clazz.getName()); 45 | 46 | if (result == null) { 47 | throw new DAONotFoundException("Mapper Not found "+clazz.getName()); 48 | } 49 | 50 | return result; 51 | } 52 | 53 | public static > T getXMLListMapper(Class clazz) { 54 | MapperManager.ensureXMLListMapper(clazz); 55 | 56 | @SuppressWarnings("unchecked") 57 | T result = (T) xmlListMappersMap.get(clazz.getName()); 58 | 59 | if (result == null) { 60 | throw new DAONotFoundException("Mapper Not found "+clazz.getName()); 61 | } 62 | 63 | return result; 64 | } 65 | 66 | private static final > void ensureDatabaseMapper(Class clazz) { 67 | DatabaseMapper result = databaseMappersMap.get(clazz.getName()); 68 | if (result == null) { 69 | try { 70 | databaseMappersMap.put(clazz.getName(), clazz.newInstance()); 71 | log.debug("Initiated DatabaseMapper: "+clazz.getName()); 72 | } 73 | catch (Exception e) {} 74 | } 75 | } 76 | 77 | private static final > void ensureXMLMapper(Class clazz) { 78 | XMLMapper result = xmlMappersMap.get(clazz.getName()); 79 | if (result == null) { 80 | try { 81 | xmlMappersMap.put(clazz.getName(), clazz.newInstance()); 82 | log.debug("Initiated XMLMapper: "+clazz.getName()); 83 | } 84 | catch (Exception e) {} 85 | } 86 | } 87 | 88 | private static final > void ensureXMLListMapper(Class clazz) { 89 | XMLListMapper result = xmlListMappersMap.get(clazz.getName()); 90 | if (result == null) { 91 | try { 92 | xmlListMappersMap.put(clazz.getName(), clazz.newInstance()); 93 | log.debug("Initiated XMLListDatabaseMapper: "+clazz.getName()); 94 | } 95 | catch (Exception e) {} 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/network/crypt/CRC32.java: -------------------------------------------------------------------------------- 1 | package koserver.common.network.crypt; 2 | 3 | public class CRC32 { 4 | 5 | static int[] table = { 6 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 7 | 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 8 | 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 9 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 10 | 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 11 | 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 12 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 13 | 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 14 | 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 15 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 16 | 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 17 | 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 18 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 19 | 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 20 | 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 21 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 22 | 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 23 | 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 24 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 25 | 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 26 | 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 27 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 28 | 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 29 | 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 30 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 31 | 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 32 | 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 33 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 34 | 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 35 | 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 36 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 37 | 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,}; 38 | 39 | public static int CalculateCRC32(byte[] data, int length, int startValue) { 40 | int crc32val = startValue; 41 | for (int i = 0; i < length; i++) { 42 | crc32val = table[(crc32val ^ data[i]) & 0xFF] ^ (crc32val >> 8); 43 | } 44 | return crc32val; 45 | } 46 | } -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/models/account/Account.java: -------------------------------------------------------------------------------- 1 | package koserver.game.models.account; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | import javolution.util.FastList; 7 | import koserver.common.enums.AccountAuthority; 8 | import koserver.common.models.AbstractModel; 9 | import koserver.game.models.player.Player; 10 | import koserver.game.services.AccountService; 11 | 12 | public class Account extends AbstractModel { 13 | 14 | private String login; 15 | private String password; 16 | private int nation; 17 | private AccountAuthority authority; 18 | private Date access; 19 | private Date creation; 20 | private List players; 21 | private AccountService connection; 22 | 23 | public Account(final Integer id) { 24 | super(id); 25 | } 26 | 27 | public Account() { 28 | super(null); 29 | } 30 | 31 | public String getLogin() { 32 | return login; 33 | } 34 | 35 | public void setLogin(final String login) { 36 | this.login = login; 37 | } 38 | 39 | public String getPassword() { 40 | return password; 41 | } 42 | 43 | public void setPassword(final String password) { 44 | this.password = password; 45 | } 46 | 47 | public int getNation() { 48 | return nation; 49 | } 50 | 51 | public void setNation(int nation) { 52 | this.nation = nation; 53 | } 54 | 55 | public AccountAuthority getAuthority() { 56 | return authority; 57 | } 58 | 59 | public void setAuthority(AccountAuthority authority) { 60 | this.authority = authority; 61 | } 62 | 63 | public boolean isBanned() { 64 | return authority == AccountAuthority.BANNED; 65 | } 66 | 67 | public void setBanned(final boolean banned) { 68 | authority = AccountAuthority.BANNED; 69 | } 70 | 71 | public Date getAccess() { 72 | return access; 73 | } 74 | 75 | public void setAccess(final Date access) { 76 | this.access = access; 77 | } 78 | 79 | public AccountService getConnection() { 80 | return connection; 81 | } 82 | 83 | public void setConnection(final AccountService connection) { 84 | this.connection = connection; 85 | } 86 | 87 | public List getPlayers() { 88 | if (players == null) { 89 | players = new FastList<>(); 90 | } 91 | return players; 92 | } 93 | 94 | public Player getPlayerById(final int playerId) { 95 | for (final Player player : this.getPlayers()) { 96 | if (player.getId() == playerId) { 97 | return player; 98 | } 99 | } 100 | 101 | return null; 102 | } 103 | 104 | public void setPlayers(final List players) { 105 | this.players = players; 106 | } 107 | 108 | public void addPlayer(final Player player) { 109 | this.getPlayers().add(player); 110 | } 111 | 112 | public Date getCreation() { 113 | return creation; 114 | } 115 | 116 | public void setCreation(Date creation) { 117 | this.creation = creation; 118 | } 119 | 120 | @Override 121 | public int hashCode() { 122 | return 0; 123 | } 124 | 125 | @Override 126 | public boolean equals(final Object obj) { 127 | if (this == obj) { 128 | return true; 129 | } 130 | if (!super.equals(obj)) { 131 | return false; 132 | } 133 | if (!(obj instanceof Account)) { 134 | return false; 135 | } 136 | final Account other = (Account) obj; 137 | if (access != other.access) { 138 | return false; 139 | } 140 | if (connection == null) { 141 | if (other.connection != null) { 142 | return false; 143 | } 144 | } else if (!connection.equals(other.connection)) { 145 | return false; 146 | } 147 | if (login == null) { 148 | if (other.login != null) { 149 | return false; 150 | } 151 | } else if (!login.equals(other.login)) { 152 | return false; 153 | } 154 | if (password == null) { 155 | if (other.password != null) { 156 | return false; 157 | } 158 | } else if (!password.equals(other.password)) { 159 | return false; 160 | } 161 | return true; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/mapper/database/PlayerMapper.java: -------------------------------------------------------------------------------- 1 | package koserver.game.mapper.database; 2 | 3 | import koserver.common.entity.AbstractEntity; 4 | import koserver.common.mapper.MapperManager; 5 | import koserver.common.mapper.database.DatabaseMapper; 6 | import koserver.common.models.AbstractModel; 7 | import koserver.game.database.entity.AccountEntity; 8 | import koserver.game.database.entity.PlayerEntity; 9 | import koserver.game.models.account.Account; 10 | import koserver.game.models.player.Player; 11 | 12 | public class PlayerMapper extends DatabaseMapper { 13 | 14 | @Override 15 | public PlayerEntity map(final Player model, final AbstractEntity linkedEntity) { 16 | final PlayerEntity playerEntity = new PlayerEntity(model.getId()); 17 | 18 | // DIRECT 19 | playerEntity.setCharacterSlot(model.getCharacterSlot()); 20 | playerEntity.setName(model.getName()); 21 | playerEntity.setRace(model.getRace()); 22 | playerEntity.setPlayerClass(model.getPlayerClass()); 23 | playerEntity.setLevel(model.getLevel()); 24 | playerEntity.setHair(model.getHair()); 25 | playerEntity.setFace(model.getFace()); 26 | playerEntity.setExperience(model.getExperience()); 27 | playerEntity.setMoney(model.getMoney()); 28 | playerEntity.setHp(model.getHp()); 29 | playerEntity.setMp(model.getMp()); 30 | playerEntity.setStrength(model.getStrength()); 31 | playerEntity.setStamina(model.getStamina()); 32 | playerEntity.setDextery(model.getDextery()); 33 | playerEntity.setIntelligence(model.getIntelligence()); 34 | playerEntity.setMagic(model.getMagic()); 35 | playerEntity.setCreationTime(model.getCreationTime()); 36 | playerEntity.setDeletionTime(model.getDeletionTime()); 37 | playerEntity.setLastOnlineTime(model.getLastOnlineTime()); 38 | playerEntity.setOnline(model.isOnline()); 39 | playerEntity.setItems(model.getItems()); 40 | playerEntity.setMapId(model.getMapId()); 41 | playerEntity.setX(model.getX()); 42 | playerEntity.setY(model.getY()); 43 | playerEntity.setZ(model.getZ()); 44 | 45 | // ACCOUNT 46 | if (linkedEntity instanceof AccountEntity) { 47 | playerEntity.setAccount((AccountEntity) linkedEntity); 48 | } else { 49 | playerEntity.setAccount(MapperManager.getDatabaseMapper(AccountMapper.class).map(model.getAccount(), playerEntity)); 50 | } 51 | 52 | return playerEntity; 53 | } 54 | 55 | @Override 56 | public Player map(final PlayerEntity entity, final AbstractModel linkedModel) { 57 | final Player player = new Player(entity.getId()); 58 | 59 | // DIRECT 60 | player.setCharacterSlot(entity.getCharacterSlot()); 61 | player.setName(entity.getName()); 62 | player.setRace(entity.getRace()); 63 | player.setPlayerClass(entity.getPlayerClass()); 64 | player.setLevel(entity.getLevel()); 65 | player.setHair(entity.getHair()); 66 | player.setFace(entity.getFace()); 67 | player.setExperience(entity.getExperience()); 68 | player.setMoney(entity.getMoney()); 69 | player.setHp(entity.getHp()); 70 | player.setMp(entity.getMp()); 71 | player.setStrength(entity.getStrength()); 72 | player.setStamina(entity.getStamina()); 73 | player.setDextery(entity.getDextery()); 74 | player.setIntelligence(entity.getIntelligence()); 75 | player.setMagic(entity.getMagic()); 76 | player.setCreationTime(entity.getCreationTime()); 77 | player.setDeletionTime(entity.getDeletionTime()); 78 | player.setLastOnlineTime(entity.getLastOnlineTime()); 79 | player.setOnline(entity.isOnline()); 80 | player.setItems(entity.getItems()); 81 | player.setMapId(entity.getMapId()); 82 | player.setX(entity.getX()); 83 | player.setY(entity.getY()); 84 | player.setZ(entity.getZ()); 85 | 86 | // ACCOUNT 87 | if (linkedModel instanceof Account) { 88 | player.setAccount((Account) linkedModel); 89 | } else { 90 | player.setAccount(MapperManager.getDatabaseMapper(AccountMapper.class).map(entity.getAccount())); 91 | } 92 | 93 | return player; 94 | } 95 | 96 | @Override 97 | public boolean equals(final Player model, final PlayerEntity entity) { 98 | return model.getName().equals(entity.getName()); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/services/ThreadPoolService.java: -------------------------------------------------------------------------------- 1 | package koserver.game.services; 2 | 3 | import java.util.Collections; 4 | import java.util.Iterator; 5 | import java.util.Map; 6 | import java.util.Map.Entry; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.Future; 9 | import java.util.concurrent.ScheduledExecutorService; 10 | import java.util.concurrent.ScheduledFuture; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | import javolution.util.FastMap; 14 | import koserver.common.services.AbstractService; 15 | import koserver.game.configuration.GlobalConfig; 16 | import koserver.game.tasks.AbstractTask; 17 | import koserver.game.tasks.TaskTypeEnum; 18 | 19 | import org.apache.log4j.Logger; 20 | 21 | public class ThreadPoolService extends AbstractService { 22 | 23 | /** LOGGER */ 24 | private static Logger log = Logger.getLogger(ThreadPoolService.class.getName()); 25 | 26 | private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(GlobalConfig.GLOBAL_THREADPOOL_POOL_SIZE); 27 | private final Map, ScheduledFuture> tasks = Collections.synchronizedMap(new FastMap, ScheduledFuture>()); 28 | 29 | private ThreadPoolService() { 30 | } 31 | 32 | @Override 33 | public void onInit() { 34 | log.info("ThreadPoolService started"); 35 | } 36 | 37 | @Override 38 | public void onDestroy() { 39 | log.info("ThreadPoolService stopped"); 40 | } 41 | 42 | public void scheduleTask(final AbstractTask task, final long delay, final TimeUnit timeUnit) { 43 | final Runnable runnable = new Runnable() { 44 | @Override 45 | public void run() { 46 | task.execute(); 47 | task.cancel(); 48 | } 49 | }; 50 | 51 | synchronized (tasks) { 52 | tasks.put(task, executor.schedule(runnable, delay, timeUnit)); 53 | } 54 | } 55 | 56 | public void scheduleRepeatableTask(final AbstractTask task, final long initialDelay, final long delay, final TimeUnit timeUnit) { 57 | final Runnable runnable = new Runnable() { 58 | @Override 59 | public void run() { 60 | task.execute(); 61 | } 62 | }; 63 | 64 | synchronized (tasks) { 65 | tasks.put(task, executor.scheduleAtFixedRate(runnable, initialDelay, delay, timeUnit)); 66 | } 67 | } 68 | 69 | public Future scheduleAtFixedRate(final Runnable runnable, final long initialDelay, final long period, final TimeUnit timeUnit) { 70 | return executor.scheduleAtFixedRate(runnable, initialDelay, period, timeUnit); 71 | } 72 | 73 | public void cancelTask(final Object linkedObject, final TaskTypeEnum taskType) { 74 | synchronized (tasks) { 75 | final Iterator, ScheduledFuture>> iterator = this.tasks.entrySet().iterator(); 76 | while (iterator.hasNext()) { 77 | final Entry, ScheduledFuture> entry = iterator.next(); 78 | if (entry.getKey().getLinkedObject().equals(linkedObject) && entry.getKey().getTaskType() == taskType) { 79 | entry.getValue().cancel(true); 80 | iterator.remove(); 81 | } 82 | } 83 | } 84 | } 85 | 86 | public void cancelAllTasksByLinkedObject(final Object linkedObject) { 87 | final Iterator, ScheduledFuture>> iterator = this.tasks.entrySet().iterator(); 88 | while (iterator.hasNext()) { 89 | final Entry, ScheduledFuture> entry = iterator.next(); 90 | if (entry.getKey().getLinkedObject().equals(linkedObject)) { 91 | entry.getValue().cancel(true); 92 | iterator.remove(); 93 | } 94 | } 95 | } 96 | 97 | /** SINGLETON */ 98 | public static ThreadPoolService getInstance() { 99 | return SingletonHolder.instance; 100 | } 101 | 102 | private static class SingletonHolder { 103 | protected static final ThreadPoolService instance = new ThreadPoolService(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/services/PlayerService.java: -------------------------------------------------------------------------------- 1 | package koserver.game.services; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | import koserver.common.services.AbstractService; 7 | import koserver.game.delegate.PlayerDelegate; 8 | import koserver.game.models.account.Account; 9 | import koserver.game.models.player.Player; 10 | import koserver.game.tasks.AbstractTask; 11 | import koserver.game.tasks.player.PlayerQuitTask; 12 | 13 | import org.apache.log4j.Logger; 14 | 15 | public class PlayerService extends AbstractService { 16 | 17 | /** LOGGER */ 18 | private static Logger log = Logger.getLogger(PlayerService.class.getName()); 19 | 20 | private PlayerService() { 21 | } 22 | 23 | @Override 24 | public void onInit() { 25 | log.info("PlayerService started"); 26 | } 27 | 28 | @Override 29 | public void onDestroy() { 30 | log.info("PlayerService stopped"); 31 | } 32 | 33 | // ---- EVENT ---- // 34 | public final void onPlayerCreate(final Player player, final boolean creationSuccess) { 35 | // player.getConnection().sendPacket(new 36 | // SM_CHARACTER_CREATE(creationSuccess)); 37 | } 38 | 39 | public final void onPlayerDelete(final Player player) { 40 | 41 | } 42 | 43 | public final void onPlayerConnect(final Player player) { 44 | player.setOnline(true); 45 | 46 | // ThreadPoolService.getInstance().scheduleTask(new 47 | // PlayerAutoSaveTask(player), PlayerConfig.PLAYER_AUTO_SAVE_DELAY, 48 | // TimeUnit.SECONDS); 49 | } 50 | 51 | public void onPlayerDisconnect(final Player player) { 52 | player.setOnline(false); 53 | player.setLastOnlineTime(new Date()); 54 | 55 | // ThreadPoolService.getInstance().cancelAllTasksByLinkedObject(player); 56 | // ObjectIDService.getInstance().releaseId(ObjectFamilyEnum.fromClass(player.getClass()), 57 | // player.getUid()); 58 | } 59 | 60 | public void onPlayerUpdate(final Player player) { 61 | PlayerDelegate.updatePlayerModel(player); 62 | } 63 | 64 | // ---- EVENT ---- // 65 | 66 | public void registerPlayer(final AccountService connection, final Player player) { 67 | connection.setActivePlayer(player); 68 | player.setAccount(connection.getAccount()); 69 | 70 | this.onPlayerConnect(player); 71 | } 72 | 73 | public void disconnectPlayer(final Player player) { 74 | AbstractTask task = null; 75 | task = new PlayerQuitTask(player); 76 | ThreadPoolService.getInstance().scheduleTask(task, 0, TimeUnit.SECONDS); 77 | } 78 | 79 | /** CRUD OPERATIONS */ 80 | public void createPlayer(final AccountService connection, final Player player) { 81 | final Account account = connection.getAccount(); 82 | player.setAccount(account); 83 | account.addPlayer(player); 84 | 85 | final boolean creationSuccess = checkPlayerRequiremens(account, player); 86 | if (creationSuccess) { 87 | player.setCreationTime(new Date()); 88 | PlayerDelegate.createPlayerModel(player); 89 | } 90 | 91 | this.onPlayerCreate(player, creationSuccess); 92 | } 93 | 94 | public void deletePlayer(final int playerId) { 95 | final Player player = PlayerDelegate.readPlayerModelById(playerId); 96 | if (player == null) { 97 | return; 98 | } 99 | 100 | player.setDeletionTime(new Date()); // TODO 101 | // ThreadPoolService.getInstance().scheduleTask(new 102 | // PlayerDeleteTask(player), PlayerConfig.PLAYER_DELETE_TIMEOUT, 103 | // TimeUnit.SECONDS); 104 | this.onPlayerDelete(player); 105 | } 106 | 107 | public Player findPlayerById(final int playerId) { 108 | return PlayerDelegate.readPlayerModelById(playerId); 109 | } 110 | 111 | public Player findPlayerByName(final String name) { 112 | return PlayerDelegate.readPlayerModelByName(name); 113 | } 114 | 115 | private boolean checkPlayerRequiremens(final Account account, final Player player) { 116 | boolean creationSuccess = true; 117 | 118 | // Admin accounts doesn't have any restrictions 119 | /* 120 | * if (account.getAccess() == 0) { if (player.getPlayerClass() == 121 | * PlayerClassEnum.REAPER) { if 122 | * (!account.haveCharacterWithLevel(PlayerConfig 123 | * .PLAYER_REAPER_REQUIRE_PLAYER_MIN_LEVEL)) { creationSuccess = false; 124 | * } } } 125 | */ 126 | return creationSuccess; 127 | } 128 | 129 | /** SINGLETON */ 130 | public static PlayerService getInstance() { 131 | return SingletonHolder.instance; 132 | } 133 | 134 | private static class SingletonHolder { 135 | protected static final PlayerService instance = new PlayerService(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/services/AccountService.java: -------------------------------------------------------------------------------- 1 | package koserver.game.services; 2 | 3 | import java.io.IOException; 4 | import java.math.BigInteger; 5 | import java.net.Socket; 6 | 7 | import org.apache.log4j.Logger; 8 | 9 | import koserver.common.network.Packet; 10 | import koserver.common.network.PacketListener; 11 | import koserver.common.network.crypt.Cryptor; 12 | import koserver.common.services.AbstractService; 13 | import koserver.common.utils.ArrayUtils; 14 | import koserver.game.delegate.AccountDelegate; 15 | import koserver.game.models.account.Account; 16 | import koserver.game.models.player.Player; 17 | import koserver.game.network.PacketHandler; 18 | import static koserver.common.enums.LoginResult.*; 19 | 20 | /** 21 | * @author Kurokami Servicio para controlar la conexion con un cliente. 22 | */ 23 | public class AccountService extends AbstractService implements Runnable { 24 | 25 | private static Logger log = Logger.getLogger(AccountService.class.getName()); 26 | private Socket clientSocket; 27 | private BigInteger publicKey; 28 | private Cryptor cryptor; 29 | private PacketHandler packetHandler; 30 | private short packetSecuenceId; 31 | private Account account; 32 | private Player activePlayer; 33 | 34 | /** 35 | * Servicio para controlar la conexion con un cliente. 36 | * 37 | * @param clientSocket 38 | * Socket conectado al cliente. 39 | */ 40 | public AccountService(Socket clientSocket) { 41 | publicKey = null; 42 | this.clientSocket = clientSocket; 43 | this.packetHandler = new PacketHandler(); 44 | packetSecuenceId = 0; 45 | } 46 | 47 | @Override 48 | public void onInit() { 49 | // log.info("AccountService started"); 50 | } 51 | 52 | @Override 53 | public void onDestroy() { 54 | // log.info("AccountService stopped"); 55 | } 56 | 57 | public void onAccountConnect(final Account account) { 58 | log.info("Account " + account.getLogin() + " connected succefully"); 59 | } 60 | 61 | public final void setActivePlayer(final Player activePlayer) { 62 | this.activePlayer = activePlayer; 63 | } 64 | 65 | public final Player getActivePlayer() { 66 | return this.activePlayer; 67 | } 68 | 69 | @Override 70 | public void run() { 71 | try { 72 | PacketListener reader = new PacketListener(clientSocket.getInputStream()); 73 | packetHandler.Initialize(this); 74 | this.onInit(); 75 | while (!clientSocket.isClosed()) { 76 | try { 77 | Packet packet = reader.waitForPacket(); 78 | if (isCryptoEnabled()) { 79 | byte[] data = packet.getData(); 80 | data = cryptor.EncryptionWithCRC32(data); 81 | if (data != null) { 82 | // TODO: Check packet SecuenceID and Checksum 83 | data = ArrayUtils.arraySubset(data, 4, data.length); 84 | data = ArrayUtils.arraySubset(data, 0, data.length - 4); 85 | packetSecuenceId++; 86 | 87 | packet = new Packet(ArrayUtils.byteArrayToShort(new byte[] { data[0] }, 0)); 88 | packet.setData(data); 89 | } 90 | } 91 | packet.setData(ArrayUtils.arraySubset(packet.getData(), 1, packet.getData().length)); 92 | packetHandler.handlePacket(packet); 93 | } catch (IOException e) { 94 | // log.info("Closed connection from " + 95 | // clientSocket.getInetAddress().getHostAddress() + ":" + 96 | // clientSocket.getPort()); 97 | this.onDestroy(); 98 | return; 99 | } catch (Exception e) { 100 | log.warn("Error on client service: " + e.getMessage()); 101 | } 102 | } 103 | } catch (Exception e) { 104 | e.printStackTrace(); 105 | } 106 | this.onDestroy(); 107 | } 108 | 109 | public int authorizeAccount(final String login, final String password) { 110 | Account account = AccountDelegate.readAccountModelByLogin(login); 111 | 112 | if (account == null) { 113 | log.info("Account " + login + " tryed to login but this account isn't registered."); 114 | return AUTH_NOT_FOUND; 115 | } 116 | 117 | if (!account.getPassword().equals(password)) { 118 | log.info("Account " + login + " tryed to login with incorrect password."); 119 | return AUTH_INVALID; 120 | } 121 | 122 | if (account.isBanned()) { 123 | log.info("Banned account " + login + " tryed to login."); 124 | return AUTH_BANNED; 125 | } 126 | 127 | this.onAccountConnect(account); 128 | 129 | this.account = account; 130 | 131 | return AUTH_SUCCESS; 132 | } 133 | 134 | public Account getAccount() { 135 | return account; 136 | } 137 | 138 | public boolean isCryptoEnabled() { 139 | return publicKey != null; 140 | } 141 | 142 | public Socket getSocket() { 143 | return clientSocket; 144 | } 145 | 146 | public void setPublicKey(BigInteger key) { 147 | publicKey = key; 148 | cryptor = new Cryptor(publicKey); 149 | } 150 | 151 | public BigInteger getPublicKey() { 152 | return publicKey; 153 | } 154 | 155 | public Cryptor getCryptor() { 156 | return cryptor; 157 | } 158 | 159 | public short getPacketSecuenceId() { 160 | return packetSecuenceId; 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/utils/PropertiesUtils.java: -------------------------------------------------------------------------------- 1 | package koserver.common.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.util.Collection; 7 | import java.util.Properties; 8 | 9 | import org.apache.commons.io.FileUtils; 10 | 11 | /** 12 | * This class is designed to simplify routine job with properties 13 | * 14 | * @author SoulKeeper 15 | */ 16 | public class PropertiesUtils { 17 | /** 18 | * Loads properties by given file 19 | * 20 | * @param file 21 | * filename 22 | * @return loaded properties 23 | * @throws java.io.IOException 24 | * if can't load file 25 | */ 26 | public static Properties load(String file) throws IOException { 27 | return load(new File(file)); 28 | } 29 | 30 | /** 31 | * Loads properties by given file 32 | * 33 | * @param file 34 | * filename 35 | * @return loaded properties 36 | * @throws java.io.IOException 37 | * if can't load file 38 | */ 39 | public static Properties load(File file) throws IOException { 40 | FileInputStream fis = new FileInputStream(file); 41 | Properties p = new Properties(); 42 | p.load(fis); 43 | fis.close(); 44 | return p; 45 | } 46 | 47 | /** 48 | * Loades properties from given files 49 | * 50 | * @param files 51 | * list of string that represents files 52 | * @return array of loaded properties 53 | * @throws IOException 54 | * if was unable to read properties 55 | */ 56 | public static Properties[] load(String... files) throws IOException { 57 | Properties[] result = new Properties[files.length]; 58 | for (int i = 0; i < result.length; i++) { 59 | result[i] = load(files[i]); 60 | } 61 | return result; 62 | } 63 | 64 | /** 65 | * Loades properties from given files 66 | * 67 | * @param files 68 | * list of files 69 | * @return array of loaded properties 70 | * @throws IOException 71 | * if was unable to read properties 72 | */ 73 | public static Properties[] load(File... files) throws IOException { 74 | Properties[] result = new Properties[files.length]; 75 | for (int i = 0; i < result.length; i++) { 76 | result[i] = load(files[i]); 77 | } 78 | return result; 79 | } 80 | 81 | /** 82 | * Loads non-recursively all .property files form directory 83 | * 84 | * @param dir 85 | * string that represents directory 86 | * @return array of loaded properties 87 | * @throws IOException 88 | * if was unable to read properties 89 | */ 90 | public static Properties[] loadAllFromDirectory(String dir) throws IOException { 91 | return loadAllFromDirectory(new File(dir), false); 92 | } 93 | 94 | /** 95 | * Loads non-recursively all .property files form directory 96 | * 97 | * @param dir 98 | * directory 99 | * @return array of loaded properties 100 | * @throws IOException 101 | * if was unable to read properties 102 | */ 103 | public static Properties[] loadAllFromDirectory(File dir) throws IOException { 104 | return loadAllFromDirectory(dir, false); 105 | } 106 | 107 | /** 108 | * Loads all .property files form directory 109 | * 110 | * @param dir 111 | * string that represents directory 112 | * @param recursive 113 | * parse subdirectories or not 114 | * @return array of loaded properties 115 | * @throws IOException 116 | * if was unable to read properties 117 | */ 118 | public static Properties[] loadAllFromDirectory(String dir, boolean recursive) throws IOException { 119 | return loadAllFromDirectory(new File(dir), recursive); 120 | } 121 | 122 | /** 123 | * Loads all .property files form directory 124 | * 125 | * @param dir 126 | * directory 127 | * @param recursive 128 | * parse subdirectories or not 129 | * @return array of loaded properties 130 | * @throws IOException 131 | * if was unable to read properties 132 | */ 133 | public static Properties[] loadAllFromDirectory(File dir, boolean recursive) throws IOException { 134 | Collection files = FileUtils.listFiles(dir, new String[] { "properties" }, recursive); 135 | return load(files.toArray(new File[files.size()])); 136 | } 137 | 138 | public static String getRelativePath(File file, File folder) { 139 | String filePath = file.getAbsolutePath(); 140 | String folderPath = folder.getAbsolutePath(); 141 | if (filePath.startsWith(folderPath)) { 142 | return filePath.substring(folderPath.length() + 1); 143 | } 144 | else { 145 | return null; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/network/PacketHandler.java: -------------------------------------------------------------------------------- 1 | package koserver.login.network; 2 | 3 | import java.io.IOException; 4 | import java.math.BigInteger; 5 | import java.util.List; 6 | 7 | import org.apache.log4j.Logger; 8 | 9 | import koserver.common.network.Packet; 10 | import koserver.common.network.crypt.CryptorKey; 11 | import koserver.common.utils.ArrayUtils; 12 | import koserver.common.utils.HexDump; 13 | import koserver.login.configuration.LoginConfig; 14 | import koserver.login.database.entity.PatchEntity; 15 | import koserver.login.database.entity.ServerEntity; 16 | import koserver.login.delegate.PatchListDelegate; 17 | import koserver.login.delegate.ServerListDelegate; 18 | import koserver.login.services.AccountService; 19 | import static koserver.login.enums.Opcodes.*; 20 | 21 | public class PacketHandler { 22 | 23 | private static Logger log = Logger.getLogger(PacketHandler.class.getName()); 24 | 25 | private AccountService accountService; 26 | private PacketWriter packetWriter; 27 | 28 | public void Initialize(AccountService accountService) { 29 | this.accountService = accountService; 30 | try { 31 | packetWriter = new PacketWriter(accountService); 32 | } catch (IOException e) { 33 | log.warn("Failed to prepare client output stream"); 34 | } 35 | } 36 | 37 | public void handlePacket(Packet packet) { 38 | switch (packet.getOpcode()) { 39 | case LS_VERSION_REQ: 40 | VersionRequestHandler(packet); 41 | break; 42 | case LS_DOWNLOADINFO_REQ: 43 | DownloadInfoRequestHandler(packet); 44 | break; 45 | case LS_CRYPTION: 46 | EncriptionPublicKeyRequestHandler(packet); 47 | break; 48 | case LS_LOGIN: 49 | LoginRequestHandler(packet); 50 | break; 51 | case LS_SERVERLIST: 52 | ServerListRequestHandler(packet); 53 | break; 54 | case LS_NEWS: 55 | NewsHandler(packet); 56 | break; 57 | case LS_UNKNOW_F7: 58 | UnknowF7Handler(packet); 59 | break; 60 | default: 61 | log.warn("Unknow packet opcode> " + packet.getOpcode()); 62 | log.warn(HexDump.dumpHexString(packet.getData())); 63 | } 64 | } 65 | 66 | private void VersionRequestHandler(Packet packet) { 67 | packet = new Packet(LS_VERSION_REQ); 68 | packet.appendShort((short) LoginConfig.LOGIN_VERSION); 69 | packetWriter.sendPacket(packet); 70 | } 71 | 72 | private void DownloadInfoRequestHandler(Packet packet) { 73 | int version = ArrayUtils.byteArrayToShort(packet.getData()); 74 | packet = new Packet(LS_DOWNLOADINFO_REQ); 75 | packet.appendString(LoginConfig.LOGIN_FTP_URL); 76 | packet.appendString(LoginConfig.LOGIN_FTP_PATH); 77 | List patchList = PatchListDelegate.getPatchs(); 78 | for (PatchEntity patch : patchList) { 79 | if (patch.getVersion() < version) { 80 | patchList.remove(patch); 81 | } 82 | } 83 | packet.appendShort((short) patchList.size()); 84 | for (PatchEntity patch : patchList) { 85 | packet.appendString(patch.getFileName()); 86 | } 87 | packetWriter.sendPacket(packet); 88 | } 89 | 90 | private void EncriptionPublicKeyRequestHandler(Packet packet) { 91 | BigInteger publicKey = CryptorKey.generateKey(); 92 | String keyString = publicKey.toString(16); 93 | byte[] keyData = ArrayUtils.hexStringToByteArray(keyString); 94 | keyData = ArrayUtils.byteArrayReverse(keyData); 95 | packet = new Packet(LS_CRYPTION); 96 | packet.appendData(keyData); 97 | packetWriter.sendPacket(packet); 98 | accountService.setPublicKey(publicKey); 99 | } 100 | 101 | private void LoginRequestHandler(Packet packet) { 102 | String login = packet.getString(); 103 | String password = packet.getString(); 104 | int result = accountService.authorizeAccount(login, password); 105 | packet = new Packet(LS_LOGIN); 106 | packet.appendInt8(result); 107 | packet.appendShort((short) 7857); 108 | packet.appendString(login); 109 | packetWriter.sendPacket(packet); 110 | } 111 | 112 | private void ServerListRequestHandler(Packet packet) { 113 | short echo = packet.getShort(); 114 | List serverList = ServerListDelegate.getServers(); 115 | packet = new Packet(LS_SERVERLIST); 116 | packet.appendShort(echo); 117 | packet.appendInt8(serverList.size()); 118 | for (ServerEntity server : serverList) { 119 | packet.appendString(server.getIp()); 120 | packet.appendString(server.getName()); 121 | packet.appendShort(server.getUserCount()); 122 | packet.appendShort((short) (int) server.getId()); 123 | packet.appendShort((short) server.getCategory()); 124 | packet.appendShort(server.getUserMax()); 125 | packet.appendShort(server.getUserMaxFree()); 126 | packet.appendInt8(0); 127 | // TODO: King name and notice not implemented 128 | packet.appendString(""); 129 | packet.appendString(""); 130 | packet.appendString(""); 131 | packet.appendString(""); 132 | } 133 | packetWriter.sendPacket(packet); 134 | } 135 | 136 | private void NewsHandler(Packet packet) { 137 | packet = new Packet(LS_NEWS); 138 | packet.appendString("LoginNotice"); 139 | packet.appendString(""); 140 | packetWriter.sendPacket(packet); 141 | } 142 | 143 | private void UnknowF7Handler(Packet packet) { 144 | packet = new Packet(LS_UNKNOW_F7); 145 | packet.appendInt8(0); 146 | packetWriter.sendPacket(packet); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/config/PropertyTransformerFactory.java: -------------------------------------------------------------------------------- 1 | package koserver.common.config; 2 | 3 | import java.io.File; 4 | import java.net.InetSocketAddress; 5 | import java.util.Locale; 6 | import java.util.regex.Pattern; 7 | 8 | import koserver.common.config.exception.TransformationException; 9 | import koserver.common.config.transformers.BooleanTransformer; 10 | import koserver.common.config.transformers.ByteTransformer; 11 | import koserver.common.config.transformers.CharTransformer; 12 | import koserver.common.config.transformers.ClassTransformer; 13 | import koserver.common.config.transformers.DoubleTransformer; 14 | import koserver.common.config.transformers.EnumTransformer; 15 | import koserver.common.config.transformers.FileTransformer; 16 | import koserver.common.config.transformers.FloatTransformer; 17 | import koserver.common.config.transformers.InetSocketAddressTransformer; 18 | import koserver.common.config.transformers.IntegerTransformer; 19 | import koserver.common.config.transformers.LocaleTransformer; 20 | import koserver.common.config.transformers.LongTransformer; 21 | import koserver.common.config.transformers.PatternTransformer; 22 | import koserver.common.config.transformers.ShortTransformer; 23 | import koserver.common.config.transformers.StringArrayTransformer; 24 | import koserver.common.config.transformers.StringTransformer; 25 | 26 | public class PropertyTransformerFactory { 27 | /** 28 | * Returns property transformer or throws 29 | * {@link com.aionemu.commons.configuration.TransformationException} if 30 | * can't create new one. 31 | * 32 | * @param clazzToTransform 33 | * Class that will is going to be transformed 34 | * @param tc 35 | * {@link com.aionemu.commons.configuration.PropertyTransformer} 36 | * class that will be instantiated 37 | * @return instance of PropertyTransformer 38 | * @throws TransformationException 39 | * if can't instantiate 40 | * {@link com.aionemu.commons.configuration.PropertyTransformer} 41 | */ 42 | @SuppressWarnings("rawtypes") 43 | public static PropertyTransformer newTransformer(Class clazzToTransform, Class tc) throws TransformationException { 44 | 45 | // Just a hack, we can't set null to annotation value 46 | if (tc == PropertyTransformer.class) { 47 | tc = null; 48 | } 49 | 50 | if (tc != null) { 51 | try { 52 | return tc.newInstance(); 53 | } 54 | catch (Exception e) { 55 | throw new TransformationException("Can't instantiate property transfromer", e); 56 | } 57 | } 58 | 59 | if (clazzToTransform == Boolean.class || clazzToTransform == Boolean.TYPE) { 60 | return BooleanTransformer.SHARED_INSTANCE; 61 | } 62 | else if (clazzToTransform == Byte.class || clazzToTransform == Byte.TYPE) { 63 | return ByteTransformer.SHARED_INSTANCE; 64 | } 65 | else if (clazzToTransform == Character.class || clazzToTransform == Character.TYPE) { 66 | return CharTransformer.SHARED_INSTANCE; 67 | } 68 | else if (clazzToTransform == Double.class || clazzToTransform == Double.TYPE) { 69 | return DoubleTransformer.SHARED_INSTANCE; 70 | } 71 | else if (clazzToTransform == Float.class || clazzToTransform == Float.TYPE) { 72 | return FloatTransformer.SHARED_INSTANCE; 73 | } 74 | else if (clazzToTransform == Integer.class || clazzToTransform == Integer.TYPE) { 75 | return IntegerTransformer.SHARED_INSTANCE; 76 | } 77 | else if (clazzToTransform == Long.class || clazzToTransform == Long.TYPE) { 78 | return LongTransformer.SHARED_INSTANCE; 79 | } 80 | else if (clazzToTransform == Short.class || clazzToTransform == Short.TYPE) { 81 | return ShortTransformer.SHARED_INSTANCE; 82 | } 83 | else if (clazzToTransform == String.class) { 84 | return StringTransformer.SHARED_INSTANCE; 85 | } 86 | else if (clazzToTransform == String[].class) { 87 | return StringArrayTransformer.SHARED_INSTANCE; 88 | } 89 | else if (clazzToTransform.isEnum()) { 90 | return EnumTransformer.SHARED_INSTANCE; 91 | } 92 | else if (clazzToTransform == File.class) { 93 | return FileTransformer.SHARED_INSTANCE; 94 | } 95 | else if (InetSocketAddress.class.isAssignableFrom(clazzToTransform)) { 96 | return InetSocketAddressTransformer.SHARED_INSTANCE; 97 | } 98 | else if (clazzToTransform == Pattern.class) { 99 | return PatternTransformer.SHARED_INSTANCE; 100 | } 101 | else if (clazzToTransform == Class.class) { 102 | return ClassTransformer.SHARED_INSTANCE; 103 | } 104 | else if (clazzToTransform == Locale.class) { 105 | return LocaleTransformer.SHARED_INSTANCE; 106 | } 107 | else { 108 | throw new TransformationException("Transformer not found for class " + clazzToTransform.getName()); 109 | } 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/xml/utils/XmlMerger.java: -------------------------------------------------------------------------------- 1 | package koserver.common.xml.utils; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | import java.io.FileWriter; 8 | import java.io.IOException; 9 | import java.util.Collection; 10 | 11 | import javax.xml.namespace.QName; 12 | import javax.xml.stream.XMLEventFactory; 13 | import javax.xml.stream.XMLEventReader; 14 | import javax.xml.stream.XMLEventWriter; 15 | import javax.xml.stream.XMLInputFactory; 16 | import javax.xml.stream.XMLOutputFactory; 17 | import javax.xml.stream.XMLStreamException; 18 | import javax.xml.stream.events.Comment; 19 | import javax.xml.stream.events.StartElement; 20 | import javax.xml.stream.events.XMLEvent; 21 | 22 | import org.apache.commons.io.FileUtils; 23 | import org.apache.commons.io.FilenameUtils; 24 | 25 | public class XmlMerger { 26 | 27 | private static final XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); 28 | private static final XMLInputFactory inputFactory = XMLInputFactory.newInstance(); 29 | private static final XMLEventFactory eventFactory = XMLEventFactory.newInstance(); 30 | 31 | public final static File processFile(File xml) throws IOException, XMLStreamException { 32 | File resultFile = File.createTempFile(FilenameUtils.removeExtension(xml.getName()), ""); 33 | 34 | final XMLEventWriter writer = outputFactory.createXMLEventWriter(new BufferedWriter(new FileWriter(resultFile, false))); 35 | final XMLEventReader reader = inputFactory.createXMLEventReader(new FileReader(xml)); 36 | while (reader.hasNext()) { 37 | final XMLEvent xmlEvent = reader.nextEvent(); 38 | if (xmlEvent.isStartElement()) { 39 | if ("import".equals(xmlEvent.asStartElement().getName().getLocalPart())) { 40 | File fileToImport = new File(xml.getParentFile()+File.separator+xmlEvent.asStartElement().getAttributeByName(new QName("file")).getValue()); 41 | Boolean skipRoot = Boolean.valueOf(xmlEvent.asStartElement().getAttributeByName(new QName("skipRoot")).getValue()); 42 | if (fileToImport.isDirectory()) { 43 | Collection files = FileUtils.listFiles(fileToImport, new String[]{"xml"}, true); 44 | for (File file : files) { 45 | processImport(file, writer, skipRoot); 46 | } 47 | } else if (fileToImport.isFile()) { 48 | processImport(fileToImport, writer, skipRoot); 49 | } 50 | continue; 51 | } 52 | } 53 | 54 | if (xmlEvent.isEndElement()) { 55 | if ("import".equals(xmlEvent.asEndElement().getName().getLocalPart())) { 56 | continue; 57 | } 58 | } 59 | 60 | // skip comments. 61 | if (xmlEvent instanceof Comment) { 62 | continue; 63 | } 64 | 65 | // skip whitespaces. 66 | if (xmlEvent.isCharacters()) { 67 | if (xmlEvent.asCharacters().isWhiteSpace() || xmlEvent.asCharacters().isIgnorableWhiteSpace()) { 68 | continue; 69 | } 70 | } 71 | 72 | writer.add(xmlEvent); 73 | } 74 | 75 | reader.close(); 76 | writer.close(); 77 | 78 | return resultFile; 79 | } 80 | 81 | public final static void processImport(File file, XMLEventWriter writer, boolean skipRoot) throws FileNotFoundException, XMLStreamException { 82 | XMLEventReader reader = inputFactory.createXMLEventReader(new FileReader(file)); 83 | QName firstTagQName = null; 84 | 85 | while (reader.hasNext()) { 86 | XMLEvent event = reader.nextEvent(); 87 | if (event.isStartDocument() || event.isEndDocument()) { 88 | continue; 89 | } 90 | 91 | if (event instanceof Comment) 92 | continue; 93 | // skip white-spaces and all ignoreable white-spaces. 94 | if (event.isCharacters()) { 95 | if (event.asCharacters().isWhiteSpace() || event.asCharacters().isIgnorableWhiteSpace()) 96 | continue; 97 | } 98 | 99 | // modify root-tag of imported file. 100 | if (firstTagQName == null && event.isStartElement()) { 101 | firstTagQName = event.asStartElement().getName(); 102 | 103 | if (skipRoot) { 104 | continue; 105 | } 106 | else { 107 | StartElement old = event.asStartElement(); 108 | event = eventFactory.createStartElement(old.getName(), old.getAttributes(), null); 109 | } 110 | } 111 | 112 | // if root was skipped - skip root end too. 113 | if (event.isEndElement() && skipRoot && event.asEndElement().getName().equals(firstTagQName)) 114 | continue; 115 | 116 | // finally - write tag 117 | writer.add(event); 118 | } 119 | 120 | reader.close(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /koserver-login/src/koserver/login/services/AccountService.java: -------------------------------------------------------------------------------- 1 | package koserver.login.services; 2 | 3 | import java.io.IOException; 4 | import java.math.BigInteger; 5 | import java.net.Socket; 6 | import java.util.Date; 7 | 8 | import org.apache.log4j.Logger; 9 | 10 | import koserver.common.enums.AccountAuthority; 11 | import koserver.common.network.Packet; 12 | import koserver.common.network.PacketListener; 13 | import koserver.common.network.crypt.Cryptor; 14 | import koserver.common.services.AbstractService; 15 | import koserver.common.utils.ArrayUtils; 16 | import koserver.login.configuration.AccountConfig; 17 | import koserver.login.database.entity.AccountEntity; 18 | import koserver.login.delegate.AccountDelegate; 19 | import koserver.login.network.PacketHandler; 20 | import static koserver.common.enums.LoginResult.*; 21 | 22 | /** 23 | * @author Kurokami Servicio para controlar la conexion con un cliente. 24 | */ 25 | public class AccountService extends AbstractService implements Runnable { 26 | 27 | private static Logger log = Logger.getLogger(AccountService.class.getName()); 28 | private Socket clientSocket; 29 | private BigInteger publicKey; 30 | private Cryptor cryptor; 31 | private PacketHandler packetHandler; 32 | private short packetSecuenceId; 33 | 34 | /** 35 | * Servicio para controlar la conexion con un cliente. 36 | * 37 | * @param clientSocket 38 | * Socket conectado al cliente. 39 | */ 40 | public AccountService(Socket clientSocket) { 41 | publicKey = null; 42 | this.clientSocket = clientSocket; 43 | this.packetHandler = new PacketHandler(); 44 | packetSecuenceId = 0; 45 | } 46 | 47 | @Override 48 | public void onInit() { 49 | // log.info("AccountService started"); 50 | } 51 | 52 | @Override 53 | public void onDestroy() { 54 | // log.info("AccountService stopped"); 55 | } 56 | 57 | public void onAccountConnect(final AccountEntity account) { 58 | account.setAccess(new Date()); 59 | AccountDelegate.updateAccountEntity(account); 60 | log.info("Account " + account.getLogin() + " connected succefully"); 61 | } 62 | 63 | @Override 64 | public void run() { 65 | try { 66 | PacketListener reader = new PacketListener(clientSocket.getInputStream()); 67 | packetHandler.Initialize(this); 68 | this.onInit(); 69 | while (!clientSocket.isClosed()) { 70 | try { 71 | Packet packet = reader.waitForPacket(); 72 | if (isCryptoEnabled()) { 73 | byte[] data = packet.getData(); 74 | data = cryptor.EncryptionWithCRC32(data); 75 | if (data != null) { 76 | // TODO: Check packet SecuenceID and Checksum 77 | data = ArrayUtils.arraySubset(data, 4, data.length); 78 | data = ArrayUtils.arraySubset(data, 0, data.length - 4); 79 | packetSecuenceId++; 80 | 81 | packet = new Packet(ArrayUtils.byteArrayToShort(new byte[] { data[0] }, 0)); 82 | packet.setData(data); 83 | } 84 | } 85 | packet.setData(ArrayUtils.arraySubset(packet.getData(), 1, packet.getData().length)); 86 | packetHandler.handlePacket(packet); 87 | } catch (IOException e) { 88 | // log.info("Closed connection from " + 89 | // clientSocket.getInetAddress().getHostAddress() + ":" + 90 | // clientSocket.getPort()); 91 | this.onDestroy(); 92 | return; 93 | } catch (Exception e) { 94 | log.warn("Error on client service: " + e.getMessage()); 95 | } 96 | } 97 | } catch (Exception e) { 98 | e.printStackTrace(); 99 | } 100 | this.onDestroy(); 101 | } 102 | 103 | public int authorizeAccount(final String login, final String password) { 104 | AccountEntity account = AccountDelegate.readAccountEntityByLogin(login); 105 | if (account == null && AccountConfig.ACCOUNT_AUTOCREATE) { 106 | log.info("Account " + login + " tryed to login but this account isn't registered, creating account."); 107 | account = new AccountEntity(); 108 | account.setLogin(login); 109 | account.setPassword(password); 110 | account.setNation(0); 111 | account.setAuthority(AccountAuthority.NORMAL.getValue()); 112 | account.setCreation(new Date()); 113 | AccountDelegate.createAccountEntity(account); 114 | } 115 | 116 | if (account == null) { 117 | log.info("Account " + login + " tryed to login but this account isn't registered."); 118 | return AUTH_NOT_FOUND; 119 | } 120 | 121 | if (!account.getPassword().equals(password)) { 122 | log.info("Account " + login + " tryed to login with incorrect password."); 123 | return AUTH_INVALID; 124 | } 125 | 126 | if (account.getAuthority() == AccountAuthority.BANNED.getValue()) { 127 | log.info("Banned account " + login + " tryed to login."); 128 | return AUTH_BANNED; 129 | } 130 | 131 | this.onAccountConnect(account); 132 | 133 | return AUTH_SUCCESS; 134 | } 135 | 136 | public boolean isCryptoEnabled() { 137 | return publicKey != null; 138 | } 139 | 140 | public Socket getSocket() { 141 | return clientSocket; 142 | } 143 | 144 | public void setPublicKey(BigInteger key) { 145 | publicKey = key; 146 | cryptor = new Cryptor(publicKey); 147 | } 148 | 149 | public BigInteger getPublicKey() { 150 | return publicKey; 151 | } 152 | 153 | public Cryptor getCryptor() { 154 | return cryptor; 155 | } 156 | 157 | public short getPacketSecuenceId() { 158 | return packetSecuenceId; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /koserver-game/src/koserver/game/models/player/Player.java: -------------------------------------------------------------------------------- 1 | package koserver.game.models.player; 2 | 3 | import java.util.Date; 4 | 5 | import koserver.common.models.AbstractModel; 6 | import koserver.game.models.account.Account; 7 | import koserver.game.models.player.enums.PlayerRaceEnum; 8 | import koserver.game.models.player.enums.PlayerClassEnum; 9 | import koserver.game.services.AccountService; 10 | import static koserver.game.enums.GameSystem.*; 11 | 12 | public class Player extends AbstractModel { 13 | 14 | private int characterSlot; 15 | private String name; 16 | private PlayerRaceEnum race; 17 | private PlayerClassEnum playerClass; 18 | private int hair; 19 | private int face; 20 | private int level; 21 | private long experience; 22 | private int money; 23 | private int hp; 24 | private int mp; 25 | private short strength; 26 | private short stamina; 27 | private short dextery; 28 | private short intelligence; 29 | private short magic; 30 | private Date creationTime; 31 | private Date deletionTime; 32 | private Date lastOnlineTime; 33 | private boolean online; 34 | private byte[] items; 35 | private int mapId; 36 | private float x; 37 | private float y; 38 | private float z; 39 | private Account account; 40 | 41 | public Player(Integer id) { 42 | super(id); 43 | } 44 | 45 | public Player() { 46 | this(null); 47 | } 48 | 49 | public String getName() { 50 | return name; 51 | } 52 | 53 | public void setName(final String name) { 54 | this.name = name; 55 | } 56 | 57 | public PlayerRaceEnum getRace() { 58 | return race; 59 | } 60 | 61 | public void setRace(final PlayerRaceEnum race) { 62 | this.race = race; 63 | } 64 | 65 | public PlayerClassEnum getPlayerClass() { 66 | return playerClass; 67 | } 68 | 69 | public void setPlayerClass(final PlayerClassEnum playerClass) { 70 | this.playerClass = playerClass; 71 | } 72 | 73 | public long getExperience() { 74 | return experience; 75 | } 76 | 77 | public void setExperience(final long experience) { 78 | this.experience = experience; 79 | } 80 | 81 | public void addExperience(final int experience) { 82 | this.experience += experience; 83 | } 84 | 85 | public int getMoney() { 86 | return money; 87 | } 88 | 89 | public void setMoney(final int money) { 90 | this.money = money; 91 | } 92 | 93 | public void addMoney(final int money) { 94 | this.money += money; 95 | } 96 | 97 | public void removeMoney(final int money) { 98 | this.money -= money; 99 | } 100 | 101 | public Date getCreationTime() { 102 | return creationTime; 103 | } 104 | 105 | public void setCreationTime(final Date creationTime) { 106 | this.creationTime = creationTime; 107 | } 108 | 109 | public Date getDeletionTime() { 110 | return deletionTime; 111 | } 112 | 113 | public void setDeletionTime(final Date deletionTime) { 114 | this.deletionTime = deletionTime; 115 | } 116 | 117 | public Date getLastOnlineTime() { 118 | return lastOnlineTime; 119 | } 120 | 121 | public void setLastOnlineTime(final Date lastOnlineTime) { 122 | this.lastOnlineTime = lastOnlineTime; 123 | } 124 | 125 | public boolean isOnline() { 126 | return online; 127 | } 128 | 129 | public void setOnline(final boolean online) { 130 | this.online = online; 131 | } 132 | 133 | public byte[] getItems() { 134 | if (items == null) { 135 | return new byte[INVENTARY_TOTAL_SLOTS * 8]; 136 | } 137 | return items; 138 | } 139 | 140 | public void setItems(final byte[] items) { 141 | this.items = items; 142 | } 143 | 144 | public Account getAccount() { 145 | return account; 146 | } 147 | 148 | public void setAccount(final Account account) { 149 | this.account = account; 150 | } 151 | 152 | public int getHp() { 153 | return hp; 154 | } 155 | 156 | public void setHp(int hp) { 157 | this.hp = hp; 158 | } 159 | 160 | public int getMp() { 161 | return mp; 162 | } 163 | 164 | public void setMp(int mp) { 165 | this.mp = mp; 166 | } 167 | 168 | public short getStrength() { 169 | return strength; 170 | } 171 | 172 | public void setStrength(short strength) { 173 | this.strength = strength; 174 | } 175 | 176 | public short getStamina() { 177 | return stamina; 178 | } 179 | 180 | public void setStamina(short stamina) { 181 | this.stamina = stamina; 182 | } 183 | 184 | public short getDextery() { 185 | return dextery; 186 | } 187 | 188 | public void setDextery(short dextery) { 189 | this.dextery = dextery; 190 | } 191 | 192 | public short getIntelligence() { 193 | return intelligence; 194 | } 195 | 196 | public void setIntelligence(short intelligence) { 197 | this.intelligence = intelligence; 198 | } 199 | 200 | public short getMagic() { 201 | return magic; 202 | } 203 | 204 | public void setMagic(short magic) { 205 | this.magic = magic; 206 | } 207 | 208 | public final AccountService getConnection() { 209 | return this.getAccount().getConnection(); 210 | } 211 | 212 | @Override 213 | public int hashCode() { 214 | final int prime = 31; 215 | int result = 1; 216 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 217 | return result; 218 | } 219 | 220 | @Override 221 | public boolean equals(final Object obj) { 222 | if (this == obj) { 223 | return true; 224 | } 225 | if (!super.equals(obj)) { 226 | return false; 227 | } 228 | if (obj == null) { 229 | return false; 230 | } 231 | if (!(obj instanceof Player)) { 232 | return false; 233 | } 234 | final Player other = (Player) obj; 235 | if (!name.equals(other.name)) { 236 | return false; 237 | } 238 | return true; 239 | } 240 | 241 | public int getLevel() { 242 | return level; 243 | } 244 | 245 | public void setLevel(int level) { 246 | this.level = level; 247 | } 248 | 249 | public int getHair() { 250 | return hair; 251 | } 252 | 253 | public void setHair(int hair) { 254 | this.hair = hair; 255 | } 256 | 257 | public int getFace() { 258 | return face; 259 | } 260 | 261 | public void setFace(int face) { 262 | this.face = face; 263 | } 264 | 265 | public int getCharacterSlot() { 266 | return characterSlot; 267 | } 268 | 269 | public void setCharacterSlot(int characterSlot) { 270 | this.characterSlot = characterSlot; 271 | } 272 | 273 | public int getMapId() { 274 | return mapId; 275 | } 276 | 277 | public void setMapId(int mapId) { 278 | this.mapId = mapId; 279 | } 280 | 281 | public float getX() { 282 | return x; 283 | } 284 | 285 | public void setX(float x) { 286 | this.x = x; 287 | } 288 | 289 | public float getY() { 290 | return y; 291 | } 292 | 293 | public void setY(float y) { 294 | this.y = y; 295 | } 296 | 297 | public float getZ() { 298 | return z; 299 | } 300 | 301 | public void setZ(float z) { 302 | this.z = z; 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /koserver-common/src/koserver/common/utils/ArrayUtils.java: -------------------------------------------------------------------------------- 1 | package koserver.common.utils; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | import java.io.UnsupportedEncodingException; 10 | import java.nio.ByteBuffer; 11 | import java.security.MessageDigest; 12 | import java.security.NoSuchAlgorithmException; 13 | import java.util.zip.GZIPOutputStream; 14 | 15 | import org.apache.log4j.Logger; 16 | 17 | public class ArrayUtils { 18 | private static Logger log = Logger.getLogger(ArrayUtils.class.getName()); 19 | 20 | public static String byteArrayToHex(byte[] a) { 21 | StringBuilder sb = new StringBuilder(); 22 | for (byte b : a) { 23 | sb.append(String.format("%02x", b & 0xff)); 24 | } 25 | return sb.toString().toUpperCase(); 26 | } 27 | 28 | public static byte[] byteArrayReverse(byte[] data) { 29 | int i = 0; 30 | int j = data.length - 1; 31 | byte tmp; 32 | while (j > i) { 33 | tmp = data[j]; 34 | data[j] = data[i]; 35 | data[i] = tmp; 36 | j--; 37 | i++; 38 | } 39 | return data; 40 | } 41 | 42 | public static String byteToHex(byte b) { 43 | return String.format("%02X", b); 44 | } 45 | 46 | public static byte intToByte(int n) { 47 | return (byte) (n & 0xFF); 48 | } 49 | 50 | public static String intToHex(int n) { 51 | return Integer.toHexString(n); 52 | } 53 | 54 | public static String byteArrayToString(byte[] b) { 55 | try { 56 | return (new String(b, "UTF-8")); 57 | } catch (UnsupportedEncodingException ex) { 58 | return new String(); 59 | } 60 | } 61 | 62 | public static String byteArrayToHex(byte[] data, int start, int end) { 63 | StringBuilder sb = new StringBuilder(); 64 | for (int i = start; i < end; i++) { 65 | sb.append(String.format("%02x", data[i] & 0xFF)); 66 | } 67 | return sb.toString().toUpperCase(); 68 | } 69 | 70 | public static short byteArrayToShort(byte[] data) { 71 | return (short) ((data[1] << 8) + (data[0] & 0xff)); 72 | } 73 | 74 | public static short byteArrayToShort(byte[] data, int startPosition) { 75 | short value = 0; 76 | for (int i = 0; i < data.length - startPosition; i++) { 77 | value += ((short) data[i + startPosition] & 0xffL) << (8 * i); 78 | } 79 | return value; 80 | } 81 | 82 | public static byte byteArrayToByte(byte[] data, int position) { 83 | return data[position - 1]; 84 | } 85 | 86 | public static short byteArrayToShort(byte[] data, int start, int end) { 87 | short value = 0; 88 | int n = 0; 89 | for (int i = start; i < end; i++) { 90 | value += ((short) data[i] & 0xFFL) << (8 * n++); 91 | } 92 | return value; 93 | } 94 | 95 | public static int byteArrayToInt(byte[] data, int start, int end) { 96 | int value = 0; 97 | int n = 0; 98 | for (int i = start; i < end; i++) { 99 | value += (data[i] & 0xFFL) << (8 * n++); 100 | } 101 | return value; 102 | } 103 | 104 | public static int byteArrayToIntRight(byte[] data) { 105 | int value = 0; 106 | for (int i = 0; i < data.length; i++) { 107 | value = (value << 8) + (data[i] & 0xff); 108 | } 109 | return value; 110 | } 111 | 112 | public static int byteArrayToInt(byte[] b) { 113 | return b[0] & 0xFF | (b[1] & 0xFF) << 8 | (b[2] & 0xFF) << 16 | (b[3] & 0xFF) << 24; 114 | } 115 | 116 | public static byte[] shortToByteArray(short value) { 117 | byte[] ret = new byte[2]; 118 | ret[0] = (byte) (value & 0xff); 119 | ret[1] = (byte) ((value >> 8) & 0xff); 120 | return ret; 121 | } 122 | 123 | public static byte[] intToByteArray(int value) { 124 | byte[] ret = new byte[4]; 125 | ret[0] = (byte) (value & 0xff); 126 | ret[1] = (byte) ((value >> 8) & 0xff); 127 | ret[2] = (byte) ((value >> 16) & 0xff); 128 | ret[3] = (byte) ((value >> 24) & 0xff); 129 | return ret; 130 | } 131 | 132 | public static byte[] longToByteArray(long value) { 133 | ByteBuffer buffer = ByteBuffer.allocate(8); 134 | buffer.putLong(value); 135 | return buffer.array(); 136 | } 137 | 138 | public static String hexToString(String hex) { 139 | StringBuilder output = new StringBuilder(); 140 | for (int i = 0; i < hex.length(); i += 2) { 141 | String str = hex.substring(i, i + 2); 142 | output.append((char) Integer.parseInt(str, 16)); 143 | } 144 | return output.toString(); 145 | } 146 | 147 | public static byte[] hexStringToByteArray(String s) { 148 | int len = s.length(); 149 | byte[] data = new byte[len / 2]; 150 | for (int i = 0; i < len; i += 2) { 151 | data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); 152 | } 153 | return data; 154 | } 155 | 156 | public static byte[] arrayCopy(byte[] source, byte[] target, int start, int length) { 157 | System.arraycopy(source, start, target, 0, length); 158 | return target; 159 | } 160 | 161 | public static byte[] arraySubset(byte[] source, int srcBegin, int srcEnd) { 162 | byte destination[]; 163 | 164 | destination = new byte[srcEnd - srcBegin]; 165 | getBytes(source, srcBegin, srcEnd, destination, 0); 166 | 167 | return destination; 168 | } 169 | 170 | public static void getBytes(byte[] source, int srcBegin, int srcEnd, byte[] destination, int dstBegin) { 171 | System.arraycopy(source, srcBegin, destination, dstBegin, srcEnd - srcBegin); 172 | } 173 | 174 | public static byte[] compressByteArray(byte[] stream) { 175 | ByteArrayOutputStream compressedStream = new ByteArrayOutputStream(stream.length); 176 | try { 177 | GZIPOutputStream zipStream = new GZIPOutputStream(compressedStream); 178 | zipStream.write(stream); 179 | zipStream.close(); 180 | compressedStream.close(); 181 | return compressedStream.toByteArray(); 182 | } catch (IOException e) { 183 | return null; 184 | } 185 | } 186 | 187 | public static String SHAsum(byte[] data) { 188 | try { 189 | MessageDigest md = MessageDigest.getInstance("SHA-1"); 190 | return byteArrayToHex(md.digest(data)); 191 | } catch (NoSuchAlgorithmException e) { 192 | return ""; 193 | } 194 | } 195 | 196 | public static boolean storeToFile(String file, byte[] data) { 197 | try { 198 | OutputStream out = new FileOutputStream(file); 199 | out.write(data); 200 | out.close(); 201 | return true; 202 | } catch (IOException e) { 203 | log.warn("ArrayUtils::storeToFile error: " + e.getMessage()); 204 | return false; 205 | } 206 | } 207 | 208 | public static byte[] readFromFile(String file) { 209 | try { 210 | // File fi = new File(file); 211 | // return Files.readAllBytes(fi.toPath()); 212 | 213 | InputStream in = new FileInputStream(file); 214 | byte[] buffer = new byte[in.available()]; 215 | in.read(buffer); 216 | in.close(); 217 | return buffer; 218 | } catch (IOException e) { 219 | log.warn("ArrayUtils::readFromFile error: " + e.getMessage()); 220 | return null; 221 | } 222 | } 223 | } --------------------------------------------------------------------------------