├── .gitignore ├── LICENSE ├── README.md ├── api └── pom.xml ├── bukkit ├── pom.xml └── src │ └── main │ ├── java │ └── fr │ │ └── creart │ │ └── gamestack │ │ └── bukkit │ │ └── BukkitStack.java │ └── resources │ └── plugin.yml ├── bungee ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── fr │ │ └── creart │ │ └── gamestack │ │ └── bungee │ │ ├── BungeeStack.java │ │ └── listener │ │ ├── MessagePacketListener.java │ │ └── PlayerTeleportRequestListener.java │ └── resources │ └── plugin.yml ├── client ├── pom.xml └── src │ └── main │ ├── java │ └── fr │ │ └── creart │ │ └── gamestack │ │ └── client │ │ └── Main.java │ └── resources │ └── messages.properties ├── common ├── pom.xml └── src │ ├── main │ ├── java │ │ └── fr │ │ │ └── creart │ │ │ └── gamestack │ │ │ └── common │ │ │ ├── Commons.java │ │ │ ├── alerting │ │ │ ├── AlertingManager.java │ │ │ ├── AlertingModule.java │ │ │ ├── DiscordAlertingModule.java │ │ │ └── SlackAlertingModule.java │ │ │ ├── app │ │ │ └── Application.java │ │ │ ├── broking │ │ │ ├── AbstractBrokerManager.java │ │ │ └── BrokerManager.java │ │ │ ├── conf │ │ │ ├── Configuration.java │ │ │ ├── ConfigurationLoadException.java │ │ │ └── PropertiesConfiguration.java │ │ │ ├── connection │ │ │ ├── ConnectionContainer.java │ │ │ ├── ConnectionData.java │ │ │ ├── ConnectionState.java │ │ │ ├── ConnectionTask.java │ │ │ ├── ConnectionTasksManager.java │ │ │ ├── database │ │ │ │ ├── AbstractDatabase.java │ │ │ │ ├── AbstractRequest.java │ │ │ │ ├── Database.java │ │ │ │ ├── DatabaseConnectionData.java │ │ │ │ ├── RequestType.java │ │ │ │ └── sql │ │ │ │ │ ├── MariaDB.java │ │ │ │ │ ├── MySQL.java │ │ │ │ │ ├── PostgreSQL.java │ │ │ │ │ ├── SQLDatabase.java │ │ │ │ │ └── SQLRequest.java │ │ │ └── rmq │ │ │ │ ├── Rabbit.java │ │ │ │ ├── RabbitConnectionData.java │ │ │ │ └── RabbitContainer.java │ │ │ ├── game │ │ │ ├── Game.java │ │ │ ├── GameMap.java │ │ │ ├── GameStatus.java │ │ │ └── Gamegrams.java │ │ │ ├── io │ │ │ └── FileUtil.java │ │ │ ├── lang │ │ │ ├── AtomicWrapper.java │ │ │ ├── BasicWrapper.java │ │ │ ├── ClassUtil.java │ │ │ ├── Decimals.java │ │ │ ├── MoreArrays.java │ │ │ ├── MoreStrings.java │ │ │ ├── Streams.java │ │ │ ├── UnsafeRunnable.java │ │ │ ├── Validation.java │ │ │ └── Wrapper.java │ │ │ ├── log │ │ │ ├── CommonLogger.java │ │ │ └── CustomLayout.java │ │ │ ├── metric │ │ │ ├── BrokerMetricOutput.java │ │ │ ├── Metric.java │ │ │ ├── MetricOutput.java │ │ │ ├── MetricPriority.java │ │ │ ├── MetricProvider.java │ │ │ ├── MetricTask.java │ │ │ └── MetricsManager.java │ │ │ ├── misc │ │ │ ├── Callback.java │ │ │ ├── Chrono.java │ │ │ ├── Configurable.java │ │ │ ├── DependsManager.java │ │ │ ├── Destroyable.java │ │ │ ├── FileDependingInstance.java │ │ │ ├── Initialisable.java │ │ │ ├── JsonUtil.java │ │ │ ├── KeptAlive.java │ │ │ └── URLUtil.java │ │ │ ├── pipeline │ │ │ ├── Pipeline.java │ │ │ ├── PipelineProvider.java │ │ │ └── SimplePipeline.java │ │ │ ├── player │ │ │ ├── Connectable.java │ │ │ ├── Contactable.java │ │ │ ├── MessageType.java │ │ │ ├── Party.java │ │ │ ├── Player.java │ │ │ └── Queueable.java │ │ │ ├── protocol │ │ │ ├── PacketListener.java │ │ │ ├── ProtocolWrap.java │ │ │ └── packet │ │ │ │ ├── EnqueuePacket.java │ │ │ │ ├── HostUpdatePacket.java │ │ │ │ ├── MessagePacket.java │ │ │ │ ├── MetricPacket.java │ │ │ │ ├── MinecraftServerStatusPacket.java │ │ │ │ ├── PlayerTeleportPacket.java │ │ │ │ ├── PullQueuePacket.java │ │ │ │ ├── Util.java │ │ │ │ └── result │ │ │ │ ├── EnqueueData.java │ │ │ │ ├── HostUpdate.java │ │ │ │ ├── HostedData.java │ │ │ │ ├── KeepAliveStatus.java │ │ │ │ ├── MessageResult.java │ │ │ │ ├── MinecraftServerUpdate.java │ │ │ │ ├── MultiPlayerData.java │ │ │ │ ├── PlayerTeleport.java │ │ │ │ ├── PullQueueData.java │ │ │ │ └── SocketHostData.java │ │ │ ├── text │ │ │ └── Translator.java │ │ │ └── thread │ │ │ ├── ThreadsManager.java │ │ │ └── ThreadsUtil.java │ └── resources │ │ └── network.properties │ └── test │ └── java │ └── fr │ └── creart │ └── gamestack │ └── common │ └── test │ ├── DecimalsTest.java │ ├── FilesTest.java │ └── ValidationTest.java ├── netty-util ├── pom.xml └── src │ └── main │ └── java │ └── fr │ └── creart │ └── gamestack │ └── netty │ ├── NettyUtil.java │ └── protocol │ ├── SimplePacket.java │ ├── SimplePacketDecoder.java │ └── SimplePacketEncoder.java ├── pom.xml └── server ├── README.md ├── pom.xml └── src └── main ├── java └── fr │ └── creart │ └── gamestack │ └── server │ ├── Main.java │ ├── StackServer.java │ ├── command │ ├── Command.java │ ├── CommandSender.java │ ├── CommandsManager.java │ ├── ConsoleSender.java │ ├── HelpCommand.java │ └── StopCommand.java │ ├── conf │ └── ConfigurationConstants.java │ ├── listener │ ├── EnqueueListener.java │ ├── HostUpdateListener.java │ ├── MinecraftUpdateListener.java │ ├── PlayerEnqueueListener.java │ └── PullQueueListener.java │ ├── logging │ ├── AuthenticationHandler.java │ ├── LogFileHandler.java │ └── LoggingServer.java │ ├── queue │ ├── PlayerQueue.java │ └── QueuesManager.java │ ├── server │ ├── HostServer.java │ └── MinecraftServer.java │ └── util │ └── Queueables.java └── resources ├── gamestack.properties ├── log4j.xml ├── messages.properties └── requests.properties /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea/ 3 | *.iml 4 | 5 | ### GameStack files 6 | logs/ 7 | 8 | ### Maven template 9 | target/ 10 | pom.xml.tag 11 | pom.xml.releaseBackup 12 | pom.xml.versionsBackup 13 | pom.xml.next 14 | release.properties 15 | dependency-reduced-pom.xml 16 | buildNumber.properties 17 | .mvn/timing.properties 18 | ### Eclipse template 19 | 20 | .metadata 21 | bin/ 22 | tmp/ 23 | *.tmp 24 | *.bak 25 | *.swp 26 | *~.nib 27 | local.properties 28 | .settings/ 29 | .loadpath 30 | .recommenders 31 | 32 | # Eclipse Core 33 | .project 34 | 35 | # External tool builders 36 | .externalToolBuilders/ 37 | 38 | # Locally stored "Eclipse launch configurations" 39 | *.launch 40 | 41 | # PyDev specific (Python IDE for Eclipse) 42 | *.pydevproject 43 | 44 | # CDT-specific (C/C++ Development Tooling) 45 | .cproject 46 | 47 | # JDT-specific (Eclipse Java Development Tools) 48 | .classpath 49 | 50 | # Java annotation processor (APT) 51 | .factorypath 52 | 53 | # PDT-specific (PHP Development Tools) 54 | .buildpath 55 | 56 | # sbteclipse plugin 57 | .target 58 | 59 | # Tern plugin 60 | .tern-project 61 | 62 | # TeXlipse plugin 63 | .texlipse 64 | 65 | # STS (Spring Tool Suite) 66 | .springBeans 67 | 68 | # Code Recommenders 69 | .recommenders/ 70 | ### Java template 71 | *.class 72 | 73 | # Mobile Tools for Java (J2ME) 74 | .mtj.tmp/ 75 | 76 | # Package Files # 77 | *.jar 78 | *.war 79 | *.ear 80 | 81 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 82 | hs_err_pid* 83 | 84 | ## File-based project format: 85 | *.iws 86 | 87 | ## Plugin-specific files: 88 | 89 | # IntelliJ 90 | /out/ 91 | 92 | # mpeltonen/sbt-idea plugin 93 | .idea_modules/ 94 | 95 | # JIRA plugin 96 | atlassian-ide-plugin.xml 97 | 98 | # Crashlytics plugin (for Android Studio and IntelliJ) 99 | com_crashlytics_export_strings.xml 100 | crashlytics.properties 101 | crashlytics-build.properties 102 | fabric.properties 103 | 104 | ### Python template 105 | # Byte-compiled / optimized / DLL files 106 | __pycache__/ 107 | *.py[cod] 108 | *$py.class 109 | 110 | # C extensions 111 | *.so 112 | 113 | # Distribution / packaging 114 | .Python 115 | env/ 116 | build/ 117 | develop-eggs/ 118 | dist/ 119 | downloads/ 120 | eggs/ 121 | .eggs/ 122 | lib/ 123 | lib64/ 124 | parts/ 125 | sdist/ 126 | var/ 127 | *.egg-info/ 128 | .installed.cfg 129 | *.egg 130 | 131 | # PyInstaller 132 | # Usually these files are written by a python script from a template 133 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 134 | *.manifest 135 | *.spec 136 | 137 | # Installer logs 138 | pip-log.txt 139 | pip-delete-this-directory.txt 140 | 141 | # Unit test / coverage reports 142 | htmlcov/ 143 | .tox/ 144 | .coverage 145 | .coverage.* 146 | .cache 147 | nosetests.xml 148 | coverage.xml 149 | *,cover 150 | .hypothesis/ 151 | 152 | # Translations 153 | *.mo 154 | *.pot 155 | 156 | # Django stuff: 157 | *.log 158 | local_settings.py 159 | 160 | # Flask stuff: 161 | instance/ 162 | .webassets-cache 163 | 164 | # Scrapy stuff: 165 | .scrapy 166 | 167 | # Sphinx documentation 168 | docs/_build/ 169 | 170 | # PyBuilder 171 | 172 | # IPython Notebook 173 | .ipynb_checkpoints 174 | 175 | # pyenv 176 | .python-version 177 | 178 | # celery beat schedule file 179 | celerybeat-schedule 180 | 181 | # dotenv 182 | .env 183 | 184 | # virtualenv 185 | venv/ 186 | ENV/ 187 | 188 | # Spyder project settings 189 | .spyderproject 190 | 191 | # Rope project settings 192 | .ropeproject 193 | -------------------------------------------------------------------------------- /api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | all 7 | fr.creart.gamestack 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | api 13 | 14 | 15 | -------------------------------------------------------------------------------- /bukkit/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | all 13 | fr.creart.gamestack 14 | 1.0-SNAPSHOT 15 | 16 | 4.0.0 17 | 18 | bukkit 19 | 20 | 21 | 22 | org.bukkit 23 | bukkit 24 | 1.9-R0.1-SNAPSHOT 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /bukkit/src/main/java/fr/creart/gamestack/bukkit/BukkitStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.bukkit; 8 | 9 | import org.bukkit.event.Listener; 10 | import org.bukkit.plugin.java.JavaPlugin; 11 | 12 | /** 13 | * @author Creart 14 | */ 15 | public class BukkitStack extends JavaPlugin { 16 | 17 | @Override 18 | public void onEnable() 19 | { 20 | } 21 | 22 | @Override 23 | public void onDisable() 24 | { 25 | } 26 | 27 | private void registerListeners(Listener... listeners) 28 | { 29 | for (Listener listener : listeners) 30 | getServer().getPluginManager().registerEvents(listener, this); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /bukkit/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | main: fr.creart.gamestack.bukkit.BukkitStack 2 | name: BukkitStack 3 | version: 1.0.0 4 | author: Creart 5 | description: Bukkit part of the GameStack project. -------------------------------------------------------------------------------- /bungee/README.md: -------------------------------------------------------------------------------- 1 | Where am I? 2 | -------- 3 | This is the BungeeCord part of the GameStack project. 4 | Note: the project uses Waterfall (a BungeeCord fork, with some changes). -------------------------------------------------------------------------------- /bungee/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 13 | all 14 | fr.creart.gamestack 15 | 1.0-SNAPSHOT 16 | 17 | 18 | 4.0.0 19 | 20 | bungee 21 | 22 | 23 | 24 | http://repo.md-5.net/content/groups/public/# 25 | md_5-repo 26 | 27 | 28 | 29 | 30 | 31 | net.md-5 32 | bungeecord-api 33 | 1.9-SNAPSHOT 34 | jar 35 | provided 36 | 37 | 38 | fr.creart.gamestack 39 | common 40 | 1.0-SNAPSHOT 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /bungee/src/main/java/fr/creart/gamestack/bungee/BungeeStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.bungee; 8 | 9 | import fr.creart.gamestack.bungee.listener.MessagePacketListener; 10 | import fr.creart.gamestack.bungee.listener.PlayerTeleportRequestListener; 11 | import fr.creart.gamestack.common.Commons; 12 | import fr.creart.gamestack.common.protocol.ProtocolWrap; 13 | import net.md_5.bungee.api.plugin.Command; 14 | import net.md_5.bungee.api.plugin.Listener; 15 | import net.md_5.bungee.api.plugin.Plugin; 16 | 17 | /** 18 | * @author Creart 19 | */ 20 | public class BungeeStack extends Plugin { 21 | 22 | private static BungeeStack instance; 23 | 24 | public BungeeStack() 25 | { 26 | instance = this; 27 | } 28 | 29 | @Override 30 | public void onEnable() 31 | { 32 | Commons.getInstance().getMessageBroker().registerListener(ProtocolWrap.MESSAGE_PACKET_ID, new MessagePacketListener()); 33 | Commons.getInstance().getMessageBroker().registerListener(ProtocolWrap.PLAYER_TELEPORT_PACKET_ID, new PlayerTeleportRequestListener()); 34 | } 35 | 36 | @Override 37 | public void onDisable() 38 | { 39 | 40 | } 41 | 42 | private void registerCommands(Command... commands) 43 | { 44 | for (Command command : commands) 45 | getProxy().getPluginManager().registerCommand(this, command); 46 | } 47 | 48 | private void registerListeners(Listener... listeners) 49 | { 50 | for (Listener listener : listeners) 51 | getProxy().getPluginManager().registerListener(this, listener); 52 | } 53 | 54 | /** 55 | * Returns the single instance of the BungeeStack class 56 | * 57 | * @return the single instance of the BungeeStack class 58 | */ 59 | public static BungeeStack getInstance() 60 | { 61 | return instance; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /bungee/src/main/java/fr/creart/gamestack/bungee/listener/MessagePacketListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.bungee.listener; 8 | 9 | import com.google.common.base.Strings; 10 | import fr.creart.gamestack.common.protocol.PacketListener; 11 | import fr.creart.gamestack.common.protocol.packet.result.MessageResult; 12 | import java.util.Arrays; 13 | import java.util.Objects; 14 | import java.util.UUID; 15 | import net.md_5.bungee.api.ChatMessageType; 16 | import net.md_5.bungee.api.ProxyServer; 17 | import net.md_5.bungee.api.chat.TextComponent; 18 | 19 | /** 20 | * @author Creart 21 | */ 22 | @SuppressWarnings("deprecation") 23 | public class MessagePacketListener implements PacketListener { 24 | 25 | @Override 26 | public void handlePacket(int packetId, MessageResult result) 27 | { 28 | ProxyServer server = ProxyServer.getInstance(); 29 | 30 | if (!Strings.isNullOrEmpty(result.getMessage())) 31 | Arrays.stream(result.getPlayerUUIDs()).map(uuid -> server.getPlayer(UUID.fromString(uuid))).filter(Objects::nonNull) 32 | .forEach(player -> { 33 | switch (result.getType()) { 34 | case ACTION_BAR: 35 | player.sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(result.getMessage())); 36 | break; 37 | case TITLE: 38 | player.sendTitle(ProxyServer.getInstance().createTitle().subTitle(new TextComponent(result.getMessage()))); 39 | break; 40 | case CHAT_MESSAGE: 41 | default: 42 | player.sendMessage(result.getMessage()); 43 | } 44 | }); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /bungee/src/main/java/fr/creart/gamestack/bungee/listener/PlayerTeleportRequestListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.bungee.listener; 8 | 9 | import fr.creart.gamestack.common.protocol.PacketListener; 10 | import fr.creart.gamestack.common.protocol.packet.result.PlayerTeleport; 11 | import java.util.Arrays; 12 | import java.util.Objects; 13 | import java.util.UUID; 14 | import net.md_5.bungee.api.ProxyServer; 15 | import net.md_5.bungee.api.config.ServerInfo; 16 | 17 | /** 18 | * @author Creart 19 | */ 20 | public class PlayerTeleportRequestListener implements PacketListener { 21 | 22 | @Override 23 | public void handlePacket(int packetId, PlayerTeleport result) 24 | { 25 | ProxyServer server = ProxyServer.getInstance(); 26 | ServerInfo info = server.getServerInfo(result.getTargetServer()); 27 | if (info != null) { 28 | Arrays.stream(result.getPlayerUUIDs()).map(uuid -> server.getPlayer(UUID.fromString(uuid))).filter(Objects::nonNull) 29 | .forEach(player -> player.connect(info)); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /bungee/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | main: fr.creart.gamestack.bungee.BungeeStack 2 | name: BungeeStack 3 | version: 1.0.0 4 | author: Creart -------------------------------------------------------------------------------- /client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | all 7 | fr.creart.gamestack 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | client 13 | 14 | 15 | 16 | fr.creart.gamestack 17 | common 18 | 1.0-SNAPSHOT 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /client/src/main/java/fr/creart/gamestack/client/Main.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.client; 8 | 9 | import fr.creart.gamestack.common.app.Application; 10 | 11 | /** 12 | * @author Creart 13 | */ 14 | public class Main extends Application { 15 | 16 | public static void main(String[] args) 17 | { 18 | new Main().startup("GameStack Client", "Client"); 19 | } 20 | 21 | @Override 22 | protected void load() 23 | { 24 | 25 | } 26 | 27 | @Override 28 | public void run() 29 | { 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /client/src/main/resources/messages.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olsdavis/GameStack/84446848a121185e9343373474e7bad7376da083/client/src/main/resources/messages.properties -------------------------------------------------------------------------------- /common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | all 7 | fr.creart.gamestack 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | common 13 | 14 | 15 | 16 | jitpack.io 17 | https://jitpack.io 18 | 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 4.12 26 | 27 | 28 | com.google.guava 29 | guava 30 | 19.0 31 | 32 | 33 | com.google.code.gson 34 | gson 35 | 2.6.1 36 | 37 | 38 | log4j 39 | log4j 40 | 1.2.17 41 | 42 | 43 | log4j 44 | apache-log4j-extras 45 | 1.2.17 46 | 47 | 48 | org.yaml 49 | snakeyaml 50 | 1.17 51 | 52 | 53 | com.github.creart 54 | ProtoColt 55 | 1.1.1 56 | 57 | 58 | org.mariadb.jdbc 59 | mariadb-java-client 60 | 1.4.6 61 | 62 | 63 | postgresql 64 | postgresql 65 | 9.1-901-1.jdbc4 66 | 67 | 68 | mysql 69 | mysql-connector-java 70 | 6.0.3 71 | 72 | 73 | com.rabbitmq 74 | amqp-client 75 | 3.5.4 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/alerting/AlertingManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.alerting; 8 | 9 | /** 10 | * @author Creart 11 | */ 12 | public abstract class AlertingManager { 13 | 14 | //TODO 15 | 16 | public enum Priority { 17 | INFO, 18 | WARNING, 19 | FATAL 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/alerting/AlertingModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.alerting; 8 | 9 | import fr.creart.gamestack.common.alerting.AlertingManager.Priority; 10 | 11 | /** 12 | * Represents a module which can alert the administrators/users of GameStack 13 | * 14 | * @author Creart 15 | */ 16 | public abstract class AlertingModule { 17 | 18 | /** 19 | * Alerts 20 | * 21 | * @param priority Priority of the message 22 | * @param message Message to send 23 | */ 24 | public abstract void alert(Priority priority, String message); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/alerting/DiscordAlertingModule.java: -------------------------------------------------------------------------------- 1 | package fr.creart.gamestack.common.alerting; 2 | 3 | import fr.creart.gamestack.common.alerting.AlertingManager.Priority; 4 | 5 | /** 6 | * @author Creart 7 | */ 8 | public class DiscordAlertingModule extends AlertingModule { 9 | 10 | @Override 11 | public void alert(Priority priority, String message) 12 | { 13 | 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/alerting/SlackAlertingModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.alerting; 8 | 9 | import fr.creart.gamestack.common.alerting.AlertingManager.Priority; 10 | 11 | /** 12 | * Alerting module for Slack 13 | * 14 | * @author Creart 15 | */ 16 | public class SlackAlertingModule extends AlertingModule { 17 | 18 | @Override 19 | public void alert(Priority priority, String message) 20 | { 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/app/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.app; 8 | 9 | import fr.creart.gamestack.common.Commons; 10 | import fr.creart.gamestack.common.lang.Decimals; 11 | import fr.creart.gamestack.common.lang.UnsafeRunnable; 12 | import fr.creart.gamestack.common.log.CommonLogger; 13 | import fr.creart.gamestack.common.misc.Chrono; 14 | import java.util.concurrent.TimeUnit; 15 | 16 | /** 17 | * Represents an application 18 | * 19 | * @author Creart 20 | */ 21 | public abstract class Application implements UnsafeRunnable { 22 | 23 | /** 24 | * Runs the usual initialisation steps and the program itself. 25 | * 26 | * @param soft software's name 27 | * @param logger logger's name 28 | */ 29 | protected final void startup(String soft, String logger) 30 | { 31 | CommonLogger.createLogger(logger); 32 | CommonLogger.info("Starting up " + soft + "..."); 33 | Chrono chrono = new Chrono(); 34 | chrono.markStart(TimeUnit.MILLISECONDS); 35 | 36 | try { 37 | load(); 38 | } catch (Exception e) { 39 | CommonLogger.fatal("Encountered an unhandled exception during the startup.", e); 40 | CommonLogger.fatal("Exiting..."); 41 | System.exit(1); 42 | } 43 | 44 | chrono.markEnd(TimeUnit.MILLISECONDS); 45 | CommonLogger.info("Done (~" + Decimals.firstDecimals((double) chrono.differenceAs(TimeUnit.MILLISECONDS, TimeUnit.MILLISECONDS) / 1000, 1) + "s.)"); 46 | 47 | byte code = 0; // lol bytecode (it's a joke, of course...) 48 | 49 | try { 50 | run(); 51 | } catch (Exception e) { 52 | CommonLogger.fatal("An unhandled exception has been encountered during the execution of the program.", e); 53 | code = 1; 54 | } finally { 55 | Commons.getInstance().close(); 56 | } 57 | 58 | CommonLogger.info("Thank you for using GameStack. Good-bye!"); 59 | CommonLogger.close(); 60 | System.exit(code); 61 | } 62 | 63 | protected abstract void load() throws Exception; 64 | 65 | } 66 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/broking/AbstractBrokerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.broking; 8 | 9 | import com.google.common.base.Preconditions; 10 | import com.google.common.collect.HashMultimap; 11 | import com.google.common.collect.Multimap; 12 | import fr.creart.gamestack.common.connection.ConnectionContainer; 13 | import fr.creart.gamestack.common.connection.ConnectionData; 14 | import fr.creart.gamestack.common.protocol.PacketListener; 15 | import fr.creart.gamestack.common.protocol.ProtocolWrap; 16 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 17 | 18 | /** 19 | * {@inheritDoc} 20 | * @author Creart 21 | */ 22 | public abstract class AbstractBrokerManager 23 | extends ConnectionContainer implements BrokerManager { 24 | 25 | protected Multimap listeners = HashMultimap.create(); 26 | 27 | /** 28 | * {@inheritDoc} 29 | */ 30 | public AbstractBrokerManager(int threads) 31 | { 32 | super(threads); 33 | } 34 | 35 | @Override 36 | public void registerListener(int packetId, PacketListener listener) 37 | { 38 | Preconditions.checkArgument(ProtocolWrap.hasPacket(packetId), "packet not declared"); 39 | Preconditions.checkNotNull(listener, "listener should not be null"); 40 | 41 | listeners.put(packetId, listener); 42 | } 43 | 44 | @Override 45 | public final

void publish(ByteArrayPacket

packet, P output) 46 | { 47 | Preconditions.checkNotNull(packet, "packet can't be null"); 48 | Preconditions.checkNotNull(output, "output can't be null"); 49 | 50 | if (connectionState.get().isUsable()) 51 | doPublish(packet, output); 52 | else 53 | logger.error("Could not publish packet (id=" + packet.getId() 54 | + ", protocol=" + packet.getProtocolName() 55 | + ") because the connection is not currently usable."); 56 | } 57 | 58 | protected abstract

void doPublish(ByteArrayPacket

packet, P output); 59 | 60 | protected final String packetChannelName(int packetId) 61 | { 62 | return "packet:" + packetId; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/broking/BrokerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.broking; 8 | 9 | import fr.creart.gamestack.common.protocol.PacketListener; 10 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 11 | import java.util.Arrays; 12 | 13 | /** 14 | * Manages the message broker. 15 | * 16 | * @author Creart 17 | */ 18 | public interface BrokerManager { 19 | 20 | /** 21 | * Registers a listener which will be called each time a packet of the precised id will be received. 22 | * 23 | * @param packetId packet's id 24 | * @param listener packet listener 25 | */ 26 | void registerListener(int packetId, PacketListener listener); 27 | 28 | /** 29 | * Registers multiple listeners. 30 | * 31 | * @param packetId packet's id 32 | * @param listeners packet listener 33 | * @see #registerListener(int, PacketListener) 34 | */ 35 | default void registerListeners(int packetId, PacketListener... listeners) 36 | { 37 | Arrays.stream(listeners).forEach(listener -> registerListener(packetId, listener)); 38 | } 39 | 40 | /** 41 | * Publishes the given packet 42 | * 43 | * @param packet Packet 44 | * @param output Packet's data 45 | * @param Type of the output 46 | */ 47 | void publish(ByteArrayPacket packet, T output); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/conf/Configuration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.conf; 8 | 9 | import com.google.common.base.Preconditions; 10 | import fr.creart.gamestack.common.misc.Initialisable; 11 | import java.io.File; 12 | import org.apache.log4j.Logger; 13 | 14 | /** 15 | * Represents a configuration, from which you can obtain data by specifying its path, and where you can set/update data. 16 | * Everything is stored and read from files. 17 | * 18 | * @author Creart 19 | */ 20 | @SuppressWarnings("unchecked") 21 | public abstract class Configuration implements Initialisable { 22 | 23 | protected final Logger logger = Logger.getLogger("Configuration"); 24 | protected final File src; 25 | 26 | /** 27 | * Default constructor. 28 | * 29 | * @param src The source file. 30 | */ 31 | public Configuration(File src) 32 | { 33 | Preconditions.checkNotNull(src, "src can't be null"); 34 | Preconditions.checkArgument(src.isFile() && src.exists(), "src has to be a file and must exist"); 35 | this.src = src; 36 | } 37 | 38 | /** 39 | * Updates the value associated to the path 40 | * 41 | * @param path Path 42 | * @param object The value of the path 43 | */ 44 | public abstract void set(String path, Object object); 45 | 46 | /** 47 | * Saves the changes in the file. 48 | */ 49 | public abstract void saveChanges(); 50 | 51 | /** 52 | * Updates the value associated to the path and saves the changes 53 | * 54 | * @param path Path 55 | * @param object The value of the path 56 | */ 57 | public final void setAndSave(String path, Object object) 58 | { 59 | set(path, object); 60 | saveChanges(); 61 | } 62 | 63 | /** 64 | * Returns the value associated to the given path, def if failed 65 | * 66 | * @param path path to value 67 | * @param def default value 68 | * @param type of the object 69 | * @return the value associated to the given path 70 | */ 71 | public abstract T get(String path, T def); 72 | 73 | /** 74 | * Returns the String associated to the given path, def if failed 75 | * 76 | * @param path path to value 77 | * @param def default value 78 | * @return the String associated to the given path 79 | */ 80 | public final String getString(String path, String def) 81 | { 82 | return get(path, def); 83 | } 84 | 85 | /** 86 | * Returns the integer associated to the given path, def if failed 87 | * 88 | * @param path path to value 89 | * @param def default value 90 | * @return the integer associated to the given path 91 | */ 92 | public final int getInteger(String path, int def) 93 | { 94 | return Integer.parseInt(getString(path, String.valueOf(def))); 95 | } 96 | 97 | /** 98 | * Returns the boolean associated to the given path, def if failed 99 | * 100 | * @param path path to value 101 | * @param def default value 102 | * @return the boolean associated to the given path 103 | */ 104 | public final boolean getBoolean(String path, boolean def) 105 | { 106 | return Boolean.parseBoolean(getString(path, String.valueOf(def))); 107 | } 108 | 109 | /** 110 | * Returns the double associated to the given path, def if failed 111 | * 112 | * @param path path to value 113 | * @param def default value 114 | * @return the double associated to the given path 115 | */ 116 | public final double getDouble(String path, double def) 117 | { 118 | return Double.parseDouble(getString(path, String.valueOf(def))); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/conf/ConfigurationLoadException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.conf; 8 | 9 | /** 10 | * Exception thrown when a configuration file can't be loaded 11 | * 12 | * @author Creart 13 | */ 14 | public class ConfigurationLoadException extends Exception { 15 | 16 | /** 17 | * @param message exception message 18 | */ 19 | public ConfigurationLoadException(String message) 20 | { 21 | super(message); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/conf/PropertiesConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.conf; 8 | 9 | import java.io.File; 10 | import java.io.FileReader; 11 | import java.io.FileWriter; 12 | import java.util.Properties; 13 | 14 | /** 15 | * @author Creart 16 | */ 17 | public class PropertiesConfiguration extends Configuration { 18 | 19 | private Properties properties; 20 | 21 | public PropertiesConfiguration(File src) 22 | { 23 | super(src); 24 | } 25 | 26 | @Override 27 | public void set(String path, Object object) 28 | { 29 | properties.put(path, object); 30 | } 31 | 32 | @Override 33 | public void saveChanges() 34 | { 35 | try (FileWriter writer = new FileWriter(src)) { 36 | properties.store(writer, ""); 37 | } catch (Exception e) { 38 | logger.error(String.format("Could not save changes to .properties file (%s)", src.getName()), e); 39 | } 40 | } 41 | 42 | @SuppressWarnings("unchecked") 43 | @Override 44 | public T get(String path, T def) 45 | { 46 | Object ret = properties.get(path); 47 | if (ret == null) 48 | return def; 49 | try { 50 | return (T) ret; 51 | } catch (Exception e) { 52 | // ignore exception, could not cast. 53 | return def; 54 | } 55 | } 56 | 57 | @Override 58 | public void initialise() 59 | { 60 | try { 61 | properties = new Properties(); 62 | properties.load(new FileReader(src)); 63 | } catch (Exception e) { 64 | logger.error(String.format("Could not load configuration from file %s.", src.getName()), e); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/ConnectionData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection; 8 | 9 | /** 10 | * Connection data (server's host, port, etc. + credentials) 11 | * 12 | * @author Creart 13 | */ 14 | public class ConnectionData { 15 | 16 | private final String username; 17 | private final String password; 18 | private final String host; 19 | private int port; 20 | 21 | /** 22 | * @param username user's name 23 | * @param password user's password 24 | * @param host target connection host 25 | * @param port target connection port 26 | */ 27 | public ConnectionData(String username, String password, String host, int port) 28 | { 29 | this.username = username; 30 | this.password = password; 31 | this.host = host; 32 | this.port = port; 33 | } 34 | 35 | public String getUsername() 36 | { 37 | return username; 38 | } 39 | 40 | public String getPassword() 41 | { 42 | return password; 43 | } 44 | 45 | public String getHost() 46 | { 47 | return host; 48 | } 49 | 50 | public int getPort() 51 | { 52 | return port; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/ConnectionState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection; 8 | 9 | /** 10 | * Represents primary connection states 11 | * 12 | * @author Creart 13 | */ 14 | public enum ConnectionState { 15 | 16 | OPENING(false), 17 | OPENED(true), 18 | CLOSING(false), 19 | CLOSED(false); 20 | 21 | private boolean usable; 22 | 23 | ConnectionState(boolean usable) 24 | { 25 | this.usable = usable; 26 | } 27 | 28 | /** 29 | * Returns true if at this connection state, the connection is usable 30 | * @return true if at this connection state, the connection is usable 31 | */ 32 | public boolean isUsable() 33 | { 34 | return usable; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/ConnectionTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection; 8 | 9 | import fr.creart.gamestack.common.misc.Callback; 10 | 11 | /** 12 | * A task which uses the connection of a container. 13 | * 14 | * @author Creart 15 | */ 16 | class ConnectionTask implements Runnable { 17 | 18 | private final int taskId; 19 | private ConnectionTasksManager tasksManager; 20 | private Callback task; 21 | 22 | ConnectionTask(int taskId, Callback task, ConnectionTasksManager tasksManager) 23 | { 24 | this.taskId = taskId; 25 | this.task = task; 26 | this.tasksManager = tasksManager; 27 | } 28 | 29 | int getTaskId() 30 | { 31 | return taskId; 32 | } 33 | 34 | @Override 35 | public void run() 36 | { 37 | try { 38 | task.call(tasksManager.getContainer().getConnection()); 39 | } catch (Exception e) { 40 | tasksManager.getContainer().getLogger().error("An unhandled exception occurred during the execution of the task " + taskId + ".", e); 41 | } 42 | } 43 | 44 | @Override 45 | public int hashCode() 46 | { 47 | return taskId; 48 | } 49 | 50 | @Override 51 | public boolean equals(Object obj) 52 | { 53 | return obj instanceof ConnectionTask && obj.hashCode() == hashCode(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/ConnectionTasksManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection; 8 | 9 | import fr.creart.gamestack.common.misc.Callback; 10 | import fr.creart.gamestack.common.misc.Destroyable; 11 | import java.util.concurrent.ExecutorService; 12 | import java.util.concurrent.TimeUnit; 13 | import java.util.concurrent.atomic.AtomicInteger; 14 | 15 | /** 16 | * @author Creart 17 | */ 18 | class ConnectionTasksManager implements Destroyable { 19 | 20 | private ExecutorService service; 21 | private ConnectionContainer container; 22 | private AtomicInteger taskIdCount = new AtomicInteger(); 23 | 24 | ConnectionTasksManager(ExecutorService service, ConnectionContainer container) 25 | { 26 | this.service = service; 27 | this.container = container; 28 | } 29 | 30 | /** 31 | * Creates a task, enqueues it and returns the id of the created task 32 | * 33 | * @param call the task to call 34 | * @return the id of the created task 35 | */ 36 | int enqueueTask(Callback call) 37 | { 38 | ConnectionTask task = new ConnectionTask<>(taskIdCount.incrementAndGet(), call, this); 39 | service.submit(task); 40 | return task.getTaskId(); 41 | } 42 | 43 | /** 44 | * Destroys the tasks manager 45 | */ 46 | @Override 47 | public void destroy() 48 | { 49 | taskIdCount = null; 50 | try { 51 | container.getLogger().info("Shutting down " + getContainer().getServiceName() + "'s tasks"); 52 | service.shutdown(); 53 | if (!service.awaitTermination(2, TimeUnit.SECONDS)) { 54 | StringBuilder builder = new StringBuilder(); 55 | builder.append("Could not await termination of all ").append(getContainer().getServiceName()) 56 | .append("tasks. The following tasks could not be terminated:\n"); 57 | for (Runnable runnable : service.shutdownNow()) 58 | builder.append("\t- Class: ").append(runnable.getClass().getName()); 59 | container.getLogger().error(builder.toString()); 60 | } 61 | } catch (Exception e) { 62 | container.getLogger().error("Could not close thread pool.", e); 63 | } 64 | } 65 | 66 | ConnectionContainer getContainer() 67 | { 68 | return container; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/AbstractDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database; 8 | 9 | import fr.creart.gamestack.common.connection.ConnectionContainer; 10 | 11 | /** 12 | * {@inheritDoc} 13 | * @param handled requests 14 | * @author Creart 15 | */ 16 | public abstract class AbstractDatabase, D extends DatabaseConnectionData> 17 | extends ConnectionContainer implements Database { 18 | 19 | /** 20 | * {@inheritDoc} 21 | */ 22 | public AbstractDatabase(int threads) 23 | { 24 | super(threads); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/AbstractRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database; 8 | 9 | import com.google.common.base.Preconditions; 10 | import com.sun.istack.internal.NotNull; 11 | import fr.creart.gamestack.common.misc.Callback; 12 | 13 | /** 14 | * Represents a request to a {@link Database} 15 | * 16 | * @param the requested type of the callback 17 | * @author Creart 18 | */ 19 | public abstract class AbstractRequest { 20 | 21 | protected RequestType type; 22 | private Callback callback; 23 | 24 | /** 25 | * @param type Type of request (insertion, update, query or deletion) 26 | * @param callback Called back on a query result 27 | * @see RequestType 28 | */ 29 | public AbstractRequest(@NotNull RequestType type, Callback callback) 30 | { 31 | this.type = type; 32 | if (type == RequestType.QUERY) 33 | Preconditions.checkNotNull(callback, "callback can't be null"); 34 | this.callback = callback; 35 | } 36 | 37 | /** 38 | * Returns the request's type 39 | * 40 | * @return the request's type 41 | */ 42 | public final RequestType getType() 43 | { 44 | return type; 45 | } 46 | 47 | /** 48 | * Returns the callback of the request 49 | * 50 | * @return the callback of the request 51 | */ 52 | public Callback getCallback() 53 | { 54 | return callback; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/Database.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database; 8 | 9 | /** 10 | * Represents a database connection 11 | * 12 | * @param type of requests 13 | * @author Creart 14 | */ 15 | @FunctionalInterface 16 | public interface Database> { 17 | 18 | /** 19 | * Executes the given request(s) 20 | * 21 | * @param requests The request(s) 22 | */ 23 | void executeRequests(T... requests); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/DatabaseConnectionData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.common.connection.database; 14 | 15 | import fr.creart.gamestack.common.connection.ConnectionData; 16 | 17 | /** 18 | * @author Creart 19 | */ 20 | public class DatabaseConnectionData extends ConnectionData { 21 | 22 | private String database; 23 | 24 | /** 25 | * {@inheritDoc} 26 | * 27 | * @param database database name 28 | */ 29 | public DatabaseConnectionData(String username, String password, String host, int port, String database) 30 | { 31 | super(username, password, host, port); 32 | this.database = database; 33 | } 34 | 35 | public String getDatabase() 36 | { 37 | return database; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/RequestType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database; 8 | 9 | /** 10 | * Represents the type of a database request 11 | * 12 | * @author Creart 13 | */ 14 | public enum RequestType { 15 | 16 | QUERY, 17 | INSERT, 18 | UPDATE, 19 | DELETE 20 | 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/sql/MariaDB.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database.sql; 8 | 9 | /** 10 | * MariaDB implementation 11 | * 12 | * @author Creart 13 | */ 14 | public class MariaDB extends SQLDatabase { 15 | 16 | /** 17 | * {@inheritDoc} 18 | */ 19 | public MariaDB(int threads) 20 | { 21 | super(threads); 22 | databaseSystemName = "mariadb"; 23 | driver = "org.mariadb.jdbc.Driver"; 24 | } 25 | 26 | @Override 27 | protected String getServiceName() 28 | { 29 | return "MariaDB"; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/sql/MySQL.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database.sql; 8 | 9 | /** 10 | * MySQL implementation 11 | * 12 | * @author Creart 13 | */ 14 | public class MySQL extends SQLDatabase { 15 | 16 | /** 17 | * {@inheritDoc} 18 | */ 19 | public MySQL(int threads) 20 | { 21 | super(threads); 22 | driver = "com.mysql.jdbc.Driver"; 23 | } 24 | 25 | @Override 26 | protected String getServiceName() 27 | { 28 | return "MySQL"; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/sql/PostgreSQL.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database.sql; 8 | 9 | /** 10 | * PostgreSQL implementation 11 | * 12 | * @author Creart 13 | */ 14 | public class PostgreSQL extends SQLDatabase { 15 | 16 | /** 17 | * {@inheritDoc} 18 | */ 19 | public PostgreSQL(int threads) 20 | { 21 | super(threads); 22 | driver = "org.postgresql.Driver"; 23 | } 24 | 25 | @Override 26 | protected String getServiceName() 27 | { 28 | return "PostgreSQL"; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/database/sql/SQLRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.database.sql; 8 | 9 | import fr.creart.gamestack.common.connection.database.AbstractRequest; 10 | import fr.creart.gamestack.common.connection.database.RequestType; 11 | import fr.creart.gamestack.common.misc.Callback; 12 | import java.sql.ResultSet; 13 | 14 | /** 15 | * Represents a SQL request to the database 16 | * 17 | * @author Creart 18 | */ 19 | public class SQLRequest extends AbstractRequest { 20 | 21 | private String request; 22 | 23 | /** 24 | * @param type request's type. If it is a query, please use the other constructor with the callback. 25 | * @param request the sql request 26 | */ 27 | public SQLRequest(RequestType type, String request) 28 | { 29 | this(type, request, null); 30 | } 31 | 32 | /** 33 | * @param type request's type 34 | * @param request the sql request 35 | * @param queryCallback the callback, called when the query is executed 36 | */ 37 | public SQLRequest(RequestType type, String request, Callback queryCallback) 38 | { 39 | super(type, queryCallback); 40 | this.request = request; 41 | } 42 | 43 | /** 44 | * Returns the SQL request 45 | * 46 | * @return the SQL request 47 | */ 48 | public String getRequest() 49 | { 50 | return request; 51 | } 52 | 53 | @Override 54 | public String toString() 55 | { 56 | return "SQLRequest{request" + request + ", request_type=" + type.name() + "}"; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/rmq/Rabbit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.rmq; 8 | 9 | import com.rabbitmq.client.Channel; 10 | import com.rabbitmq.client.Connection; 11 | import java.io.Closeable; 12 | import java.io.IOException; 13 | import java.util.concurrent.TimeoutException; 14 | 15 | /** 16 | * Contains RMQ's connection and channel. 17 | * I had to wrap up these two values in order to make the RMQ client compatible with my {@link fr.creart.gamestack.common.connection.ConnectionContainer} 18 | * system. 19 | * 20 | * @author Creart 21 | */ 22 | class Rabbit implements Closeable { 23 | 24 | private RabbitContainer container; 25 | private Connection connection; 26 | private Channel channel; 27 | 28 | Rabbit(RabbitContainer container, Connection connection, Channel channel) 29 | { 30 | this.container = container; 31 | this.connection = connection; 32 | this.channel = channel; 33 | } 34 | 35 | Connection getConnection() 36 | { 37 | return connection; 38 | } 39 | 40 | Channel getChannel() 41 | { 42 | return channel; 43 | } 44 | 45 | void setConnection(Connection connection) 46 | { 47 | this.connection = connection; 48 | } 49 | 50 | void setChannel(Channel channel) 51 | { 52 | this.channel = channel; 53 | } 54 | 55 | @Override 56 | public void close() throws IOException 57 | { 58 | if (channel.isOpen()) 59 | try { 60 | channel.close(); 61 | } catch (TimeoutException e) { 62 | container.getLogger().error("Connection with the RabbitMQ server timed out.", e); 63 | } 64 | 65 | if (connection.isOpen()) 66 | connection.close(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/connection/rmq/RabbitConnectionData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.connection.rmq; 8 | 9 | import fr.creart.gamestack.common.connection.ConnectionData; 10 | 11 | /** 12 | * @author Creart 13 | */ 14 | public class RabbitConnectionData extends ConnectionData { 15 | 16 | private String virtualHost; 17 | 18 | /** 19 | * {@inheritDoc} 20 | * 21 | * @param virtualHost the rabbitmq virtual host 22 | */ 23 | public RabbitConnectionData(String username, String password, String host, int port, String virtualHost) 24 | { 25 | super(username, password, host, port); 26 | this.virtualHost = virtualHost; 27 | } 28 | 29 | public String getVirtualHost() 30 | { 31 | return virtualHost; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/game/Game.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.game; 8 | 9 | import fr.creart.gamestack.common.misc.FileDependingInstance; 10 | import java.util.Map; 11 | 12 | /** 13 | * Represents a game 14 | * 15 | * @author Creart 16 | */ 17 | public class Game extends FileDependingInstance { 18 | 19 | private static FileDependingInstance gameParent; 20 | 21 | static { 22 | // TODO: load the default required files for games 23 | } 24 | 25 | private final int id; 26 | private final String name; 27 | private final Map maps; 28 | 29 | /** 30 | * Default constructor 31 | * 32 | * @param id game's id 33 | * @param name game's name 34 | * @param maps game's maps 35 | * @param requiredFiles game's required files 36 | */ 37 | public Game(int id, String name, Map maps, String... requiredFiles) 38 | { 39 | this(id, name, requiredFiles, maps, gameParent); 40 | } 41 | 42 | /** 43 | * Constructor where the parent {@link FileDependingInstance} is explicit – which is {@link #gameParent} by default. 44 | * 45 | * @param id game id 46 | * @param name game name 47 | * @param requiredFiles game required files (assets) 48 | * @param maps game maps 49 | * @param parent the parent {@link FileDependingInstance} 50 | */ 51 | public Game(int id, String name, String[] requiredFiles, Map maps, FileDependingInstance parent) 52 | { 53 | this.id = id; 54 | this.name = name; 55 | this.requiredFiles = requiredFiles; 56 | this.maps = maps; 57 | setParent(parent); 58 | } 59 | 60 | /** 61 | * Returns game's id 62 | * 63 | * @return game's id 64 | */ 65 | public int getId() 66 | { 67 | return id; 68 | } 69 | 70 | /** 71 | * Returns game's name 72 | * 73 | * @return game's name 74 | */ 75 | public String getName() 76 | { 77 | return name; 78 | } 79 | 80 | /** 81 | * Returns the GameMap associated to the given id 82 | * 83 | * @param mapId map's id 84 | * @return the GameMap associated to the given id 85 | */ 86 | public GameMap getMap(int mapId) 87 | { 88 | return maps.get(mapId); 89 | } 90 | 91 | @Override 92 | public boolean equals(Object obj) 93 | { 94 | return obj instanceof Game && obj.hashCode() == hashCode(); 95 | } 96 | 97 | @Override 98 | public int hashCode() 99 | { 100 | return id; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/game/GameMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.game; 8 | 9 | import com.google.common.base.Charsets; 10 | import fr.creart.gamestack.common.misc.FileDependingInstance; 11 | import fr.creart.protocolt.util.MoreArrays; 12 | 13 | /** 14 | * @author Creart 15 | */ 16 | public class GameMap extends FileDependingInstance { 17 | 18 | private int id; 19 | private Game game; 20 | private String name; 21 | // gamegrams 22 | private float gg; 23 | // additional gamegrams per player 24 | private float ggpp; 25 | 26 | /** 27 | * Default constructor 28 | * 29 | * @param id map's id 30 | * @param game the game 31 | * @param name map's name 32 | * @param gg gamegrams 33 | * @param ggpp gamegrams added for each player 34 | * @param requiredFiles the required files 35 | */ 36 | public GameMap(int id, Game game, String name, float gg, float ggpp, String... requiredFiles) 37 | { 38 | super(requiredFiles); 39 | this.id = id; 40 | this.game = game; 41 | this.name = name; 42 | this.gg = gg; 43 | this.ggpp = ggpp; 44 | } 45 | 46 | /** 47 | * Returns current map's id 48 | * 49 | * @return current map's id 50 | */ 51 | public int getId() 52 | { 53 | return id; 54 | } 55 | 56 | /** 57 | * Returns current map's game 58 | * 59 | * @return current map's game 60 | */ 61 | public Game getGame() 62 | { 63 | return game; 64 | } 65 | 66 | /** 67 | * Returns current map's name 68 | * 69 | * @return current map's name 70 | */ 71 | public String getName() 72 | { 73 | return name; 74 | } 75 | 76 | /** 77 | * Returns the needed amount of gamegrams for this game depending on the number of players 78 | * 79 | * @param players the number of players 80 | * @return the needed amount of gamegrams for this game depending on the number of players 81 | */ 82 | public float calculateGamegrams(short players) 83 | { 84 | return players * ggpp + gg; 85 | } 86 | 87 | @Override 88 | public int hashCode() 89 | { 90 | return 31 * MoreArrays.sum(name.getBytes(Charsets.UTF_8)); 91 | } 92 | 93 | @Override 94 | public boolean equals(Object obj) 95 | { 96 | if (!(obj instanceof GameMap)) 97 | return false; 98 | GameMap other = (GameMap) obj; 99 | return game.equals(other.game) && obj.hashCode() == hashCode(); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/game/GameStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.game; 8 | 9 | /** 10 | * Represents game statuses 11 | * 12 | * @author Creart 13 | */ 14 | public enum GameStatus { 15 | 16 | LOBBY((byte) 0), 17 | STARTING((byte) 1), 18 | STARTED((byte) 2), 19 | FINISHED((byte) 3); 20 | 21 | private byte id; 22 | 23 | GameStatus(byte id) 24 | { 25 | this.id = id; 26 | } 27 | 28 | public byte getId() 29 | { 30 | return id; 31 | } 32 | 33 | /** 34 | * Returns the GameStatus associated to the given id 35 | * 36 | * @param id game status' id 37 | * @return the GameStatus associated to the given id 38 | */ 39 | public static GameStatus getById(int id) 40 | { 41 | for (GameStatus status : values()) 42 | if (status.id == id) 43 | return status; 44 | return null; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/game/Gamegrams.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.game; 8 | 9 | /** 10 | * Gamegrams utils (eg: conversion) 11 | * 12 | * @author Creart 13 | */ 14 | public class Gamegrams { 15 | 16 | private static final float COEFFICIENT = 102400F; 17 | 18 | /** 19 | * Returns the amount of gamegrams for the given RAM 20 | * 21 | * @param ram amount of RAM 22 | * @return the amount of gamegrams for the given RAM 23 | */ 24 | public static float fromRam(long ram) 25 | { 26 | return (float) ram / COEFFICIENT; 27 | } 28 | 29 | /** 30 | * Returns the amount of RAM for the given gamegrams 31 | * 32 | * @param gamegrams amount of gamegrams 33 | * @return the amount of RAM for the given gamegrams 34 | */ 35 | public static long toRam(float gamegrams) 36 | { 37 | return Math.round(gamegrams * COEFFICIENT); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/AtomicWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | import java.util.concurrent.locks.ReadWriteLock; 10 | import java.util.concurrent.locks.ReentrantReadWriteLock; 11 | 12 | /** 13 | * Implementation of {@link Wrapper} for atomic values 14 | * 15 | * {@inheritDoc} 16 | * @author Creart 17 | */ 18 | public class AtomicWrapper extends Wrapper { 19 | 20 | private ReadWriteLock lock = new ReentrantReadWriteLock(); 21 | 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | public AtomicWrapper() 26 | { 27 | super(); 28 | } 29 | 30 | /** 31 | * {@inheritDoc} 32 | */ 33 | public AtomicWrapper(T value) 34 | { 35 | super(value); 36 | } 37 | 38 | @Override 39 | public void set(T value) 40 | { 41 | lock.writeLock().lock(); 42 | try { 43 | this.value = value; 44 | } finally { 45 | lock.writeLock().unlock(); 46 | } 47 | } 48 | 49 | @Override 50 | public T get() 51 | { 52 | lock.readLock().lock(); 53 | try { 54 | return value; 55 | } finally { 56 | lock.readLock().unlock(); 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/BasicWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | /** 10 | * Basic wrapper, just contains a value. 11 | * 12 | * {@inheritDoc} 13 | * @author Creart 14 | */ 15 | public class BasicWrapper extends Wrapper { 16 | 17 | /** 18 | * {@inheritDoc} 19 | */ 20 | public BasicWrapper() 21 | { 22 | super(); 23 | } 24 | 25 | /** 26 | * {@inheritDoc} 27 | */ 28 | public BasicWrapper(T value) 29 | { 30 | super(value); 31 | } 32 | 33 | @Override 34 | public void set(T value) 35 | { 36 | this.value = value; 37 | } 38 | 39 | @Override 40 | public T get() 41 | { 42 | return value; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/ClassUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | import fr.creart.gamestack.common.log.CommonLogger; 10 | 11 | /** 12 | * Some utils for classes 13 | * 14 | * @author Creart 15 | */ 16 | public class ClassUtil { 17 | 18 | private ClassUtil() 19 | { 20 | 21 | } 22 | 23 | /** 24 | * Loads the given class 25 | * 26 | * @param path path to the class 27 | */ 28 | public static void loadClass(String path) 29 | { 30 | try { 31 | Class.forName(path); 32 | } catch (Exception e) { 33 | CommonLogger.error("Could not find class for path " + path); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/Decimals.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | import java.text.DecimalFormat; 10 | import java.text.DecimalFormatSymbols; 11 | 12 | /** 13 | * Floating point utils 14 | * 15 | * @author Creart 16 | */ 17 | public class Decimals { 18 | 19 | private Decimals() 20 | { 21 | 22 | } 23 | 24 | /** 25 | * Returns the first decimals of the number 26 | * 27 | * @param number Number 28 | * @param decimals Number of decimals 29 | * @return the first decimals of the number 30 | */ 31 | public static String firstDecimals(double number, int decimals) 32 | { 33 | if ((int) Math.round(number) == 0 || decimals == 0) 34 | return ""; 35 | int dec = decimals; 36 | if (dec < 0) 37 | dec = -decimals; 38 | DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(); 39 | symbols.setDecimalSeparator('.'); 40 | DecimalFormat format = new DecimalFormat("#." + MoreStrings.repeat('#', dec)); 41 | format.setDecimalFormatSymbols(symbols); 42 | return format.format(number); 43 | } 44 | 45 | /** 46 | * Returns true if the two floats are equal 47 | * 48 | * @param first First value 49 | * @param second Second value 50 | * @return true if the two values are equal 51 | */ 52 | public static boolean equal(float first, float second) 53 | { 54 | return Float.floatToIntBits(first) == Float.floatToIntBits(second); 55 | } 56 | 57 | /** 58 | * Returns true if the two doubles are equal 59 | * 60 | * @param first First value 61 | * @param second Second value 62 | * @return true if the two doubles are equal 63 | */ 64 | public static boolean equal(double first, double second) 65 | { 66 | return Double.doubleToLongBits(first) == Double.doubleToLongBits(second); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/MoreArrays.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | import com.google.common.base.Preconditions; 10 | import java.util.function.Predicate; 11 | 12 | /** 13 | * Arrays utils 14 | * 15 | * @author Creart 16 | */ 17 | public final class MoreArrays { 18 | 19 | private MoreArrays() 20 | { 21 | // no instance 22 | } 23 | 24 | /** 25 | * Returns the last object of the given array 26 | * 27 | * @param objects Array 28 | * @param Object types 29 | * @return the last object of the given array 30 | */ 31 | public static T lastObjectOf(T[] objects) 32 | { 33 | return objects[objects.length - 1]; 34 | } 35 | 36 | /** 37 | * Concatenates the whole String array 38 | * 39 | * @param strings String array 40 | * @return the concatenation of all the Strings in the array 41 | */ 42 | public static String concat(String[] strings) 43 | { 44 | StringBuilder builder = new StringBuilder(); 45 | for (String str : strings) 46 | builder.append(str); 47 | return builder.toString(); 48 | } 49 | 50 | /** 51 | * Tests the given predicate on each given object. 52 | * Returns true if of all the objects passed predicate's test 53 | * 54 | * @param objects Object array 55 | * @param predicate The predicate 56 | * @return true if of all the objects passed predicate's test 57 | */ 58 | public static boolean isTrueForAll(T[] objects, Predicate predicate) 59 | { 60 | Preconditions.checkNotNull(predicate, "predicate can't be null"); 61 | Preconditions.checkArgument(objects.length > 0, "objects can't be null"); 62 | 63 | for (T obj : objects) 64 | if (!predicate.test(obj)) 65 | return false; 66 | return true; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/MoreStrings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | /** 10 | * String utils 11 | * 12 | * @author Creart 13 | */ 14 | public final class MoreStrings { 15 | 16 | private MoreStrings() 17 | { 18 | 19 | } 20 | 21 | /** 22 | * Returns a String which repeats the given character the demanded amount of times. 23 | * 24 | * @param c Character to repeat 25 | * @param times Times to repeat 26 | * @return a String which repeats the given character the demanded amount of times. 27 | */ 28 | public static String repeat(char c, int times) 29 | { 30 | if (times == 0) 31 | return ""; 32 | StringBuilder builder = new StringBuilder(); 33 | int fixed = times; 34 | if (fixed < 0) 35 | fixed = -fixed; 36 | for (int i = 0; i < fixed; i++) 37 | builder.append(c); 38 | return builder.toString(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/Streams.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | /** 10 | * Some stream utils 11 | * 12 | * @author Creart 13 | */ 14 | public final class Streams { 15 | 16 | private Streams() 17 | { 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/UnsafeRunnable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | /** 10 | * {@link Runnable}-like class. Used for unsafe operations which can throw exceptions. 11 | * 12 | * @author Creart 13 | */ 14 | public interface UnsafeRunnable { 15 | 16 | /** 17 | * The unsafe operation 18 | */ 19 | void run() throws Exception; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/Validation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | import java.util.Optional; 10 | 11 | /** 12 | * Result of an action, which can be a success or a failure. 13 | * It allows to keep exceptions. 14 | *

15 | * The way you can use it is when your method does not guarantee to return a correct value (an exception) 16 | * you set the return type to {@link Validation}: 17 | *

 18 |  *     
 19 |  *
 20 |  *     public static class Validation toInt(String s) {
 21 |  *         try {
 22 |  *             return new Validation.Success<>(Integer.valueOf(s));
 23 |  *         } catch (Exception e) {
 24 |  *             return new Validation.Failure<>(e);
 25 |  *         }
 26 |  *     }
 27 |  *     
 28 |  * 
29 | *

30 | * Then, the caller of the function can get to know if the operation is a success by calling the {@link #isSuccess()} 31 | * function. (You can have a look at the test: fr.creart.gamestack.common.test.ValidationTest) 32 | * 33 | * @param exception 34 | * @param value 35 | * @author François Sarradin (https://www.youtube.com/watch?v=evS3iwZLS4s) 36 | */ 37 | public abstract class Validation { 38 | 39 | private Validation() 40 | { 41 | 42 | } 43 | 44 | /** 45 | * Returns true if the operation is a success 46 | * 47 | * @return true if the operation is a success 48 | */ 49 | public final boolean isSuccess() 50 | { 51 | return this.getClass() == Success.class; 52 | } 53 | 54 | /** 55 | * Returns an {@link Optional} of the value contained by the validation 56 | * 57 | * @return an {@link Optional} of the value contained by the validation 58 | */ 59 | public abstract Optional toOptional(); 60 | 61 | /** 62 | * Returns the inverse Validation of the current one 63 | * 64 | * @return the inverse Validation of the current one 65 | */ 66 | public abstract Validation swap(); 67 | 68 | /** 69 | * Represents a case of success 70 | * 71 | * @param value 72 | * @param exception 73 | */ 74 | public static class Success extends Validation { 75 | private final T value; 76 | 77 | /** 78 | * @param value the value 79 | */ 80 | public Success(T value) 81 | { 82 | this.value = value; 83 | } 84 | 85 | @Override 86 | public Optional toOptional() 87 | { 88 | return Optional.ofNullable(value); 89 | } 90 | 91 | @Override 92 | public Validation swap() 93 | { 94 | return new Failure<>(value); 95 | } 96 | } 97 | 98 | /** 99 | * Represents a case of failure 100 | * 101 | * @param exception 102 | * @param value 103 | */ 104 | public static class Failure extends Validation { 105 | private final E exception; 106 | 107 | /** 108 | * @param exception the exception 109 | */ 110 | public Failure(E exception) 111 | { 112 | this.exception = exception; 113 | } 114 | 115 | @Override 116 | public Optional toOptional() 117 | { 118 | return Optional.empty(); 119 | } 120 | 121 | @Override 122 | public Validation swap() 123 | { 124 | return new Success<>(exception); 125 | } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/lang/Wrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.lang; 8 | 9 | /** 10 | * Represents a Wrapper 11 | * 12 | * @param the wrapped value 13 | * @author Creart 14 | */ 15 | public abstract class Wrapper { 16 | 17 | protected T value; 18 | 19 | /** 20 | * Default constructor, null value by default 21 | */ 22 | public Wrapper() 23 | { 24 | this(null); 25 | } 26 | 27 | /** 28 | * @param value wrapper's value 29 | */ 30 | public Wrapper(T value) 31 | { 32 | this.value = value; 33 | } 34 | 35 | /** 36 | * Changes the current value to the new one 37 | * 38 | * @param value The new value 39 | */ 40 | public abstract void set(T value); 41 | 42 | /** 43 | * Returns the current value 44 | * 45 | * @return the current value 46 | */ 47 | public abstract T get(); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/log/CommonLogger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.log; 8 | 9 | import org.apache.log4j.LogManager; 10 | import org.apache.log4j.Logger; 11 | 12 | /** 13 | * A common logger for all GameStack software. 14 | * 15 | * @author Creart 16 | */ 17 | public final class CommonLogger { 18 | 19 | private static Logger logger; 20 | 21 | private CommonLogger() 22 | { 23 | // no instance 24 | } 25 | 26 | /** 27 | * Creates a new logger if it has not been done yet. 28 | * 29 | * @param softName The name of the software which is using the logger. 30 | */ 31 | public static void createLogger(String softName) 32 | { 33 | if (hasLogger()) 34 | return; 35 | 36 | System.setProperty("gamestack.log_folder", "logs/" + softName.toLowerCase() + "/"); 37 | logger = Logger.getLogger(softName); 38 | 39 | info("╔═══╗───────────╔╗──────╔╗"); 40 | info("║╔═╗║──────────╔╝╚╗─────║║"); 41 | info("║║─╚╬══╦╗╔╦══╦═╩╗╔╬══╦══╣║╔╗"); 42 | info("║║╔═╣╔╗║╚╝║║═╣══╣║║╔╗║╔═╣╚╝╝"); 43 | info("║╚╩═║╔╗║║║║║═╬══║╚╣╔╗║╚═╣╔╗╗"); 44 | info("╚═══╩╝╚╩╩╩╩══╩══╩═╩╝╚╩══╩╝╚╝"); 45 | } 46 | 47 | /** 48 | * Returns true if the logger has been created. 49 | * 50 | * @return true if the logger has been created. 51 | */ 52 | public static boolean hasLogger() 53 | { 54 | return logger != null; 55 | } 56 | 57 | /** 58 | * Logs the given message as an information 59 | * 60 | * @param message The message 61 | */ 62 | public static void info(String message) 63 | { 64 | logger.info(message); 65 | } 66 | 67 | /** 68 | * Logs the given message and the attached throwable as an information 69 | * 70 | * @param message the message (https://goo.gl/g1aNsY) 71 | * @param attached attached throwable 72 | */ 73 | public static void info(String message, Throwable attached) 74 | { 75 | logger.info(message, attached); 76 | } 77 | 78 | /** 79 | * Logs the given message as a warning 80 | * 81 | * @param message The message 82 | */ 83 | public static void warn(String message) 84 | { 85 | logger.warn(message); 86 | } 87 | 88 | /** 89 | * Logs the given message as an error 90 | * 91 | * @param message The message 92 | */ 93 | public static void error(String message) 94 | { 95 | logger.error(message); 96 | } 97 | 98 | /** 99 | * Logs the given message and the attached throwable as an error 100 | * 101 | * @param message The message 102 | * @param attached The attached throwable 103 | */ 104 | public static void error(String message, Throwable attached) 105 | { 106 | logger.error(message, attached); 107 | } 108 | 109 | /** 110 | * Logs the given message as a fatal error 111 | * 112 | * @param message The message 113 | */ 114 | public static void fatal(String message) 115 | { 116 | logger.fatal(message); 117 | } 118 | 119 | /** 120 | * Logs the given message and the attached throwable as a fatal error 121 | * 122 | * @param message The message 123 | * @param attached The attached throwable 124 | */ 125 | public static void fatal(String message, Throwable attached) 126 | { 127 | logger.fatal(message, attached); 128 | } 129 | 130 | /** 131 | * Closes all created loggers 132 | */ 133 | public static void close() 134 | { 135 | LogManager.shutdown(); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/log/CustomLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.log; 8 | 9 | /** 10 | * @author Creart 11 | */ 12 | class CustomLayout { 13 | 14 | /*private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("'['HH':'mm']' "); 15 | 16 | private boolean file; 17 | 18 | /** 19 | * @param file true if the layout is for file appending (does not print debug) 20 | CustomLayout(boolean file) 21 | { 22 | this.file = file; 23 | } 24 | 25 | @Override 26 | public String format(LoggingEvent event) 27 | { 28 | if (event == null || (file && event.getLevel() == Level.DEBUG)) 29 | return null; 30 | 31 | StringBuilder builder = new StringBuilder(); // StringBuilders are more efficient than simple String concatenations 32 | builder.append(currentTime()); 33 | builder.append('[').append(event.getLogger().getName()).append("] "); 34 | builder.append(event.getLevel().toString()).append(": "); 35 | builder.append(event.getMessage()); 36 | 37 | if (event.getThrowableInformation() != null) 38 | builder.append(" Exception:\n").append(ExceptionUtils.getStackTrace(event.getThrowableInformation().getThrowable())); 39 | 40 | builder.append("\n"); 41 | 42 | return builder.toString(); 43 | } 44 | 45 | @Override 46 | public boolean ignoresThrowable() 47 | { 48 | return false; 49 | } 50 | 51 | @Override 52 | public void activateOptions() 53 | { 54 | // nothing to do here. 55 | } 56 | 57 | private static String currentTime() 58 | { 59 | return LocalDateTime.now().format(DATE_FORMAT); 60 | }*/ 61 | 62 | } 63 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/metric/BrokerMetricOutput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.metric; 8 | 9 | import fr.creart.gamestack.common.broking.BrokerManager; 10 | import fr.creart.gamestack.common.protocol.ProtocolWrap; 11 | import fr.creart.gamestack.common.protocol.packet.MetricPacket; 12 | import java.io.IOException; 13 | 14 | /** 15 | * Default metric output. 16 | * It publishes the packet on the network. 17 | * 18 | * @author Creart 19 | */ 20 | public class BrokerMetricOutput implements MetricOutput { 21 | 22 | private MetricPacket packet; 23 | private BrokerManager broker; 24 | 25 | /** 26 | * @param broker the broker manager for the output (default broker) 27 | */ 28 | public BrokerMetricOutput(BrokerManager broker) 29 | { 30 | this.broker = broker; 31 | packet = ProtocolWrap.getPacketById(0xFE); 32 | } 33 | 34 | @Override 35 | public void output(Metric metric) 36 | { 37 | if (metric == null) 38 | MetricsManager.LOGGER.warn("Tried to publish a null metric."); 39 | else 40 | broker.publish(packet, metric); 41 | } 42 | 43 | @Override 44 | public void close() throws IOException 45 | { 46 | // nothing to do here, because the broker is closed with the commons 47 | } 48 | 49 | @Override 50 | public String toString() 51 | { 52 | return "Broker"; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/metric/Metric.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.metric; 8 | 9 | import com.google.common.base.Charsets; 10 | import fr.creart.protocolt.util.MoreArrays; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * Represents an object which contains a measured data 15 | * and which is going to be propagated on the network. 16 | * 17 | * @author Creart 18 | */ 19 | public abstract class Metric implements Comparable { 20 | 21 | protected transient MetricProvider provider; 22 | protected final LocalDateTime time; 23 | private final transient MetricPriority priority; 24 | 25 | /** 26 | * @param provider source provider 27 | * @param priority metric output priority 28 | */ 29 | public Metric(MetricProvider provider, MetricPriority priority) 30 | { 31 | this(provider, priority, LocalDateTime.now()); 32 | } 33 | 34 | /** 35 | * @param provider source provider 36 | * @param priority metric priority 37 | * @param when time when the metric was measured 38 | */ 39 | public Metric(MetricProvider provider, MetricPriority priority, LocalDateTime when) 40 | { 41 | this.provider = provider; 42 | this.priority = priority; 43 | this.time = when; 44 | } 45 | 46 | /** 47 | * Returns current metric's provider 48 | * 49 | * @return current metric's provider 50 | */ 51 | public MetricProvider getProvider() 52 | { 53 | return provider; 54 | } 55 | 56 | /** 57 | * Returns current metric's priority. Higher priority metrics should be sent first 58 | * 59 | * @return current metric's priority 60 | */ 61 | public MetricPriority getPriority() 62 | { 63 | return priority; 64 | } 65 | 66 | /** 67 | * Returns the moment when the metric was measured 68 | * 69 | * @return the moment when the metric was measured 70 | */ 71 | public LocalDateTime getTime() 72 | { 73 | return time; 74 | } 75 | 76 | @Override 77 | public boolean equals(Object obj) 78 | { 79 | if (!(obj instanceof Metric)) 80 | return false; 81 | Metric other = (Metric) obj; 82 | return provider.getMetricName().equals(other.getProvider().getMetricName()) && time.equals(other.getTime()); 83 | } 84 | 85 | @Override 86 | public int hashCode() 87 | { 88 | return MoreArrays.sum(provider.getMetricName().getBytes(Charsets.UTF_8)); 89 | } 90 | 91 | @Override 92 | public int compareTo(Metric o) 93 | { 94 | if (o.getPriority().getLevel() == priority.getLevel()) 95 | return 0; 96 | return o.getPriority().getLevel() > priority.getLevel() ? 1 : -1; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/metric/MetricOutput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.metric; 8 | 9 | import java.io.Closeable; 10 | 11 | /** 12 | * Represents an object which propagates {@link Metric}s on the network. 13 | * 14 | * @author Creart 15 | */ 16 | public interface MetricOutput extends Closeable { 17 | 18 | /** 19 | * Propagates the metric to the network 20 | * 21 | * @param metric Metric to send 22 | */ 23 | void output(Metric metric) throws Exception; 24 | 25 | /** 26 | * Returns a textual representation of the metric output. (It may be its name, for instance.) 27 | * 28 | * @return Returns a textual representation of the metric output. 29 | */ 30 | @Override 31 | String toString(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/metric/MetricPriority.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.metric; 8 | 9 | /** 10 | * Represents the priority of a metric 11 | * 12 | * @author Creart 13 | */ 14 | public enum MetricPriority { 15 | 16 | LOW((short) 1), 17 | NORMAL((short) 2), 18 | HIGH((short) 3); 19 | 20 | private short level; 21 | 22 | MetricPriority(short level) 23 | { 24 | this.level = level; 25 | } 26 | 27 | /** 28 | * Returns the level of importance of the priority. Higher the level is and more it is important 29 | * 30 | * @return the level of importance of the priority 31 | */ 32 | public short getLevel() 33 | { 34 | return level; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/metric/MetricProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.metric; 8 | 9 | import java.util.concurrent.atomic.AtomicBoolean; 10 | 11 | /** 12 | * A task ran every x seconds which collects data on the network 13 | * and propagates it. (It may do something else than propagating the data if you override the {@link #getChosenOutput()} function.) 14 | * 15 | * @author Creart 16 | */ 17 | public abstract class MetricProvider { 18 | 19 | private volatile long lastUpdate = System.currentTimeMillis(); 20 | private final short updateFrequency; 21 | private AtomicBoolean lastUpdateFailed = new AtomicBoolean(false); 22 | 23 | /** 24 | * @param updateFrequency the update frequency of the provider (in milliseconds) 25 | */ 26 | public MetricProvider(short updateFrequency) 27 | { 28 | this.updateFrequency = updateFrequency; 29 | } 30 | 31 | /** 32 | * Returns the update frequency, which is the time difference between the last update and the current time 33 | * 34 | * @return the update frequency 35 | */ 36 | final short getUpdateFrequency() 37 | { 38 | return updateFrequency; 39 | } 40 | 41 | /** 42 | * Returns the last time that the provider has provided a metric 43 | * 44 | * @return the last time that the provider has provided a metric 45 | */ 46 | final synchronized long getLastUpdate() 47 | { 48 | return lastUpdate; 49 | } 50 | 51 | /** 52 | * Sets the last update to current time 53 | */ 54 | final synchronized void renewLastUpdate() 55 | { 56 | lastUpdate = System.currentTimeMillis(); 57 | } 58 | 59 | void setLastUpdateFailed(boolean lastUpdateFailed) 60 | { 61 | this.lastUpdateFailed.set(lastUpdateFailed); 62 | } 63 | 64 | /** 65 | * Returns true if the last metric update failed. (If the last {@link #provide()} call failed.) 66 | * 67 | * @return true if the last metric update failed 68 | */ 69 | public boolean hasLastUpdateFailed() 70 | { 71 | return lastUpdateFailed.get(); 72 | } 73 | 74 | /** 75 | * Called each x seconds. 76 | * Returns the collected data 77 | * 78 | * @return the collected data 79 | */ 80 | public abstract Metric provide(); 81 | 82 | /** 83 | * Returns the class of the provided metric 84 | * 85 | * @param metric's type 86 | * @return the class of the provided metric 87 | */ 88 | public abstract Class getProvidedMetric(); 89 | 90 | /** 91 | * Returns the alternative output of the current provider. null if it has none 92 | * 93 | * @return the alternative output of the current provider 94 | */ 95 | public MetricOutput getChosenOutput() 96 | { 97 | return null; 98 | } 99 | 100 | /** 101 | * Returns true if the current provider has a different output than the default propagation on the network 102 | * 103 | * @return true if the current provider has a different output than the default propagation on the network 104 | */ 105 | public final boolean hasCustomOutput() 106 | { 107 | return getChosenOutput() != null; 108 | } 109 | 110 | /** 111 | * Returns the metric name 112 | * 113 | * @return the metric name 114 | */ 115 | public abstract String getMetricName(); 116 | 117 | /** 118 | * Please describe the metric 119 | */ 120 | @Override 121 | public abstract String toString(); 122 | 123 | } 124 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/metric/MetricTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.metric; 8 | 9 | import fr.creart.gamestack.common.lang.BasicWrapper; 10 | import fr.creart.gamestack.common.lang.Wrapper; 11 | import java.util.Objects; 12 | import java.util.Set; 13 | import java.util.TreeSet; 14 | 15 | /** 16 | * @author Creart 17 | */ 18 | public class MetricTask implements Runnable { 19 | 20 | // it is quite a lot, I may reduce it 21 | private static final short MAX_PROVIDER_RUN_TIME = 500; 22 | 23 | private MetricsManager manager; 24 | 25 | public MetricTask(MetricsManager manager) 26 | { 27 | this.manager = manager; 28 | } 29 | 30 | @Override 31 | public void run() 32 | { 33 | final Wrapper runTime = new BasicWrapper<>(0L); 34 | 35 | Set output = new TreeSet<>(); 36 | 37 | manager.getProviders().stream().filter(Objects::nonNull).forEach(provider -> { 38 | // approximately equals, a metric may have taken too much time to run. 39 | if (System.currentTimeMillis() - provider.getLastUpdate() <= 10 + runTime.get() + provider.getUpdateFrequency()) { 40 | long start = System.currentTimeMillis(); // it's all the process 41 | Thread thread = new Thread(manager.getMetricsGroup(), () -> output.add(provider.provide()), "Metric Task (" + provider.toString() + ")"); 42 | thread.start(); 43 | 44 | try { 45 | thread.join(MAX_PROVIDER_RUN_TIME); 46 | } catch (InterruptedException e) { 47 | MetricsManager.LOGGER.error(String.format("Interrupted execution on metric provider task (%s)!", provider.toString()), e); 48 | } 49 | 50 | // task takes too much time 51 | if (thread.isAlive()) { 52 | thread.interrupt(); 53 | MetricsManager. 54 | LOGGER.warn("The metric provider (" + provider.toString() + ") took too much time to provide data (> 500ms)! Interrupted it."); 55 | provider.setLastUpdateFailed(true); 56 | } 57 | // don't update the metric's last execution if it failed. 58 | else { 59 | provider.renewLastUpdate(); 60 | provider.setLastUpdateFailed(false); 61 | } 62 | 63 | runTime.set(runTime.get() + System.currentTimeMillis() - start); 64 | } 65 | }); 66 | 67 | output.stream().filter(Objects::nonNull).forEach(this::sendMetric); 68 | } 69 | 70 | private void sendMetric(Metric metric) 71 | { 72 | if (metric.getProvider().hasCustomOutput()) 73 | try { 74 | metric.getProvider().getChosenOutput().output(metric); 75 | } catch (Exception e) { 76 | MetricsManager.LOGGER.error("Could not output the metric " + metric.getProvider().getMetricName() + " in the chosen output!", e); 77 | } 78 | else 79 | try { 80 | manager.getDefaultOutput().output(metric); 81 | } catch (Exception e) { 82 | MetricsManager.LOGGER.error("Could not output the metric " + metric.getProvider().getMetricName() + " in the " 83 | + metric.getProvider().getChosenOutput().toString() + " output.", e); 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/metric/MetricsManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.metric; 8 | 9 | import com.google.common.base.Preconditions; 10 | import com.google.common.collect.BiMap; 11 | import com.google.common.collect.HashBiMap; 12 | import com.google.common.collect.Sets; 13 | import fr.creart.gamestack.common.Commons; 14 | import fr.creart.gamestack.common.misc.Configurable; 15 | import fr.creart.gamestack.common.misc.Initialisable; 16 | import java.util.Set; 17 | import java.util.concurrent.Executors; 18 | import java.util.concurrent.ScheduledExecutorService; 19 | import java.util.concurrent.ScheduledFuture; 20 | import java.util.concurrent.ThreadFactory; 21 | import java.util.concurrent.TimeUnit; 22 | import org.apache.log4j.Logger; 23 | 24 | /** 25 | * This class manages metrics. 26 | * A metric is data which is propagated on the network every x millisecond. 27 | * 28 | * @author Creart 29 | */ 30 | public class MetricsManager implements Initialisable, Configurable, AutoCloseable { 31 | 32 | static final Logger LOGGER = Logger.getLogger("Metrics"); 33 | 34 | private static final byte MAX_THREADS = 4; 35 | 36 | private ThreadGroup metricsGroup; 37 | private byte threads; 38 | private ScheduledExecutorService scheduler; 39 | private volatile boolean initialised; 40 | private MetricOutput defaultOutput; 41 | private Set providers = Sets.newConcurrentHashSet(); 42 | private ScheduledFuture metricTask; 43 | private BiMap> metrics = HashBiMap.create(); 44 | 45 | /** 46 | * @param output metric output 47 | * @param threads number of allocated threads 48 | */ 49 | public MetricsManager(MetricOutput output, byte threads) 50 | { 51 | this.defaultOutput = output; 52 | this.threads = threads; 53 | } 54 | 55 | /** 56 | * Returns the currently registered providers 57 | * 58 | * @return the currently registered providers 59 | */ 60 | synchronized Set getProviders() 61 | { 62 | return providers; 63 | } 64 | 65 | /** 66 | * Registers a new provider 67 | * 68 | * @param provider The provider to register 69 | */ 70 | public void registerProvider(MetricProvider provider) 71 | { 72 | checkInitialisedState(); 73 | Preconditions.checkNotNull(provider, "provider can't be null"); 74 | 75 | synchronized (this) { 76 | providers.add(provider); 77 | } 78 | } 79 | 80 | @Override 81 | public void initialise() 82 | { 83 | if (initialised) 84 | return; 85 | 86 | metricsGroup = Commons.getInstance().getThreadsManager().newThreadGroup("Metrics"); 87 | 88 | ThreadFactory factory = Commons.getInstance().getThreadsManager().newThreadFactory(metricsGroup); 89 | scheduler = threads <= 1 ? Executors.newSingleThreadScheduledExecutor(factory) : 90 | Executors.newScheduledThreadPool(Math.min(MAX_THREADS, threads), factory); 91 | 92 | metricTask = scheduler.scheduleAtFixedRate(new MetricTask(this), 2000L, 500L, TimeUnit.MILLISECONDS); 93 | 94 | // finally 95 | initialised = true; 96 | } 97 | 98 | @Override 99 | public void close() throws Exception 100 | { 101 | metricTask.cancel(false); 102 | scheduler.shutdownNow(); 103 | } 104 | 105 | /** 106 | * Registers a metric 107 | * 108 | * @param metricName metric's name 109 | * @param metric metric's class 110 | */ 111 | public void declareMetric(String metricName, Class metric) 112 | { 113 | metrics.put(metricName, metric); 114 | } 115 | 116 | /** 117 | * Returns the metric associated to the given name 118 | * 119 | * @param metricName Metric's name 120 | * @return the metric associated to the given name 121 | */ 122 | public Class getMetric(String metricName) 123 | { 124 | return metrics.get(metricName); 125 | } 126 | 127 | /** 128 | * Returns the metric's name associated to the given class 129 | * 130 | * @param clazz metric's class 131 | * @return the metric's name associated to the given class 132 | */ 133 | public String getMetricName(Class clazz) 134 | { 135 | return metrics.inverse().get(clazz); 136 | } 137 | 138 | /** 139 | * Returns the metric default output 140 | * 141 | * @return the metric default output 142 | */ 143 | MetricOutput getDefaultOutput() 144 | { 145 | return defaultOutput; 146 | } 147 | 148 | /** 149 | * Returns the thread group used by the metrics system 150 | * 151 | * @return the thread group used by the metrics system 152 | */ 153 | ThreadGroup getMetricsGroup() 154 | { 155 | return metricsGroup; 156 | } 157 | 158 | /** 159 | * Throws an {@link IllegalStateException} if the metrics manager hasn't been initialised 160 | */ 161 | private void checkInitialisedState() 162 | { 163 | Preconditions.checkState(initialised, "not initialised"); 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/Callback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | /** 10 | * A task which is executed when the attended value is received or finally usable. 11 | * 12 | * @author Creart 13 | */ 14 | @FunctionalInterface 15 | public interface Callback { 16 | 17 | /** 18 | * Does whatever it wants with the given value. 19 | * 20 | * @param value Value 21 | */ 22 | void call(V value) throws Exception; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/Chrono.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | import java.util.concurrent.TimeUnit; 10 | 11 | /** 12 | * A "chronometer" which allows you to calculate the time passed between the two moments. 13 | * 14 | * @author Creart 15 | */ 16 | public final class Chrono { 17 | 18 | private long start; 19 | private long end; 20 | 21 | /** 22 | * Marks the position of the start. 23 | * 24 | * @param unit time unit 25 | */ 26 | public void markStart(TimeUnit unit) 27 | { 28 | start = now(unit); 29 | } 30 | 31 | /** 32 | * Marks the position of the end. 33 | * 34 | * @param unit time unit 35 | */ 36 | public void markEnd(TimeUnit unit) 37 | { 38 | end = now(unit); 39 | } 40 | 41 | /** 42 | * Returns the difference between the end and the start positions. 43 | * 44 | * @param baseUnit the unit used for the mark end and start functions 45 | * @param unit the result unit 46 | * @return the difference between the end and the start positions. 47 | */ 48 | public long differenceAs(TimeUnit baseUnit, TimeUnit unit) 49 | { 50 | long duration = end - start; 51 | switch (unit) { 52 | case NANOSECONDS: 53 | return baseUnit.toNanos(duration); 54 | case MICROSECONDS: 55 | return baseUnit.toMicros(duration); 56 | case MILLISECONDS: 57 | return baseUnit.toMillis(duration); 58 | case MINUTES: 59 | return baseUnit.toMinutes(duration); 60 | case HOURS: 61 | return baseUnit.toHours(duration); 62 | case DAYS: 63 | return baseUnit.toDays(duration); 64 | case SECONDS: 65 | default: 66 | return baseUnit.toSeconds(duration); 67 | } 68 | } 69 | 70 | private long now(TimeUnit unit) 71 | { 72 | return unit == TimeUnit.MILLISECONDS ? System.currentTimeMillis() : unit.convert(System.nanoTime(), unit); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/Configurable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | /** 10 | * Represents an object which can be configured 11 | * 12 | * @author Creart 13 | */ 14 | public interface Configurable { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/DependsManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | import fr.creart.gamestack.common.connection.database.sql.MariaDB; 10 | import fr.creart.gamestack.common.connection.database.sql.MySQL; 11 | import fr.creart.gamestack.common.connection.database.sql.PostgreSQL; 12 | import fr.creart.gamestack.common.connection.rmq.RabbitContainer; 13 | import fr.creart.protocolt.util.ReflectionUtil; 14 | import java.lang.reflect.Constructor; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | /** 19 | * @author Creart 20 | */ 21 | public class DependsManager { 22 | 23 | private Map> associations = new HashMap<>(); 24 | 25 | /** 26 | * Creates associations (name <=> constructor) 27 | */ 28 | public void createAssociations() 29 | { 30 | associations.put("mariadb", ReflectionUtil.getConstructor(MariaDB.class, int.class)); 31 | associations.put("mysql", ReflectionUtil.getConstructor(MySQL.class, int.class)); 32 | associations.put("postgres", ReflectionUtil.getConstructor(PostgreSQL.class, int.class)); 33 | associations.put("rabbitmq", ReflectionUtil.getConstructor(RabbitContainer.class, int.class)); 34 | } 35 | 36 | /** 37 | * Returns an instance created from the constructor associated to the given name 38 | * 39 | * @param name system name 40 | * @param args arguments 41 | * @return an instance created from the constructor 42 | */ 43 | public T getAssociation(String name, Object... args) 44 | { 45 | try { 46 | return (T) associations.get(name.toLowerCase()).newInstance(args); 47 | } catch (Exception e) { 48 | return null; 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/Destroyable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | /** 10 | * Represents an object which can be destroyed. 11 | * 12 | * @author Creart 13 | */ 14 | @FunctionalInterface 15 | public interface Destroyable { 16 | 17 | /** 18 | * Destroys the object. 19 | */ 20 | void destroy(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/FileDependingInstance.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | import java.util.Arrays; 10 | import org.apache.commons.lang3.ArrayUtils; 11 | 12 | /** 13 | * Represents an object, a game, an instance of anything which needs files to work properly. 14 | * These latter are given by the {@link #getRequiredFiles()} function. 15 | *

16 | * What makes this class interesting is that: 17 | *

    18 | *
  • files are represented by Strings, so you can actually put URLs or use them as you like;
  • 19 | *
  • a FileDependingInstance can have a parent, so you can actually create a "hierarchy".
  • 20 | *
21 | * 22 | * @author Creart 23 | */ 24 | public abstract class FileDependingInstance { 25 | 26 | private FileDependingInstance parent; 27 | protected String[] requiredFiles; 28 | 29 | /** 30 | * @param requiredFiles the required files 31 | */ 32 | public FileDependingInstance(String... requiredFiles) 33 | { 34 | this(null, requiredFiles); 35 | } 36 | 37 | /** 38 | * @param parent the parent instance 39 | * @param requiredFiles the required files 40 | */ 41 | public FileDependingInstance(FileDependingInstance parent, String... requiredFiles) 42 | { 43 | setParent(parent); 44 | this.requiredFiles = requiredFiles; 45 | } 46 | 47 | /** 48 | * Returns the required files of this instance, added to the required files of the parent instances. 49 | * The parent files come first. 50 | * 51 | * @return the required files of this instance, added to the required files of the parent instances 52 | */ 53 | public String[] getRequiredFiles() 54 | { 55 | if (parent == null || parent.getRequiredFiles().length == 0) 56 | return requiredFiles; 57 | return ArrayUtils.addAll(parent.getRequiredFiles(), requiredFiles); 58 | } 59 | 60 | protected void setParent(FileDependingInstance parent) 61 | { 62 | this.parent = parent; 63 | } 64 | 65 | @Override 66 | public boolean equals(Object obj) 67 | { 68 | return obj instanceof FileDependingInstance && Arrays.equals(requiredFiles, ((FileDependingInstance) obj).requiredFiles); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/Initialisable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | /** 10 | * Represents an object which can be initialised 11 | * 12 | * @author Creart 13 | */ 14 | @FunctionalInterface 15 | public interface Initialisable { 16 | 17 | /** 18 | * Initialises the object. 19 | */ 20 | void initialise(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/JsonUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | import com.google.common.base.Preconditions; 10 | import com.google.gson.Gson; 11 | import com.google.gson.GsonBuilder; 12 | import java.lang.reflect.Modifier; 13 | 14 | /** 15 | * Json utils 16 | * 17 | * @author Creart 18 | */ 19 | public final class JsonUtil { 20 | 21 | private static final Gson GSON = new GsonBuilder() 22 | .enableComplexMapKeySerialization() 23 | .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT) 24 | .create(); 25 | 26 | private JsonUtil() 27 | { 28 | 29 | } 30 | 31 | /** 32 | * Returns a textual json representation of the given object. 33 | * Transient and static fields are not serialized 34 | * 35 | * @param obj Object to serialize 36 | * @return a textual json representation of the given object 37 | */ 38 | public static String toJson(Object obj) 39 | { 40 | Preconditions.checkNotNull(obj, "object can't be null"); 41 | 42 | return GSON.toJson(obj); 43 | } 44 | 45 | /** 46 | * Returns the object deserialized from the String 47 | * 48 | * @param clazz source class 49 | * @param json source String 50 | * @return the object deserialized from the String 51 | */ 52 | public static T fromJson(Class clazz, String json) 53 | { 54 | return GSON.fromJson(json, clazz); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/KeptAlive.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | /** 10 | * Represents an object which can/has to be kept alive 11 | * 12 | * @author Creart 13 | */ 14 | public abstract class KeptAlive { 15 | 16 | private volatile long lastKeepAlive; 17 | 18 | /** 19 | * Keeps the instance alive 20 | */ 21 | public final void keepAlive() 22 | { 23 | lastKeepAlive += getAliveDifference(); 24 | } 25 | 26 | /** 27 | * Returns true if the current instance has timed out 28 | * 29 | * @return true if the current instance has timed out 30 | */ 31 | public final boolean hasTimedOut() 32 | { 33 | return lastKeepAlive + getAliveDifference() < System.currentTimeMillis(); 34 | } 35 | 36 | /** 37 | * Returns the difference between each keep alive until the instance has timed out 38 | * 39 | * @return the difference between each keep alive until the instance has timed out 40 | */ 41 | protected abstract long getAliveDifference(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/misc/URLUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.misc; 8 | 9 | import java.net.URL; 10 | import org.apache.commons.lang3.Validate; 11 | 12 | /** 13 | * @author Creart 14 | */ 15 | public final class URLUtil { 16 | 17 | private URLUtil() 18 | { 19 | // no instance 20 | } 21 | 22 | /** 23 | * Returns true if the given URL is valid 24 | * 25 | * @param url the String to test 26 | * @return true if the given URL is valid 27 | */ 28 | public static boolean isValidURL(String url) 29 | { 30 | Validate.notEmpty(url, "url cannot be null"); 31 | 32 | try { 33 | URL u = new URL(url); 34 | u.toURI(); 35 | return true; 36 | } catch (Exception e) { 37 | return false; 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/pipeline/Pipeline.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.pipeline; 8 | 9 | import java.util.Collection; 10 | 11 | /** 12 | * A series of actions which can be registered, a pipeline of actions. 13 | * To register a provider: {@link #add(PipelineProvider)} 14 | * To register multiple providers: {@link #addAll(Collection)} 15 | * To finally call the registered providers: {@link #call(Object)} 16 | * 17 | * @author Creart 18 | */ 19 | public interface Pipeline { 20 | 21 | /** 22 | * Adds a single provider provider 23 | * 24 | * @param provider provider to add 25 | */ 26 | void add(PipelineProvider provider); 27 | 28 | /** 29 | * Removes the given provider 30 | * 31 | * @param provider provider 32 | */ 33 | void remove(PipelineProvider provider); 34 | 35 | /** 36 | * Adds all the given providers 37 | * 38 | * @param providers providers to add 39 | */ 40 | void addAll(Collection> providers); 41 | 42 | /** 43 | * Calls all the registered providers with the given object 44 | * 45 | * @param object object to call with 46 | */ 47 | void call(T object); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/pipeline/PipelineProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.pipeline; 8 | 9 | /** 10 | * Represents one of the actions on the given objects of a {@link Pipeline}. 11 | * 12 | * @author Creart 13 | */ 14 | public interface PipelineProvider { 15 | 16 | /** 17 | * Called as an action when the given object has to/can be treated. 18 | * 19 | * @param t the object 20 | */ 21 | void pipeline(T t); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/pipeline/SimplePipeline.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.pipeline; 8 | 9 | import java.util.Collection; 10 | import java.util.HashSet; 11 | import java.util.Set; 12 | import org.apache.commons.lang3.Validate; 13 | 14 | /** 15 | * Default and simple implementation of the {@link Pipeline} interface. 16 | * 17 | * @author Creart 18 | */ 19 | public class SimplePipeline implements Pipeline { 20 | 21 | private Set> providers = new HashSet<>(); 22 | 23 | @Override 24 | public void addAll(Collection> add) 25 | { 26 | Validate.notEmpty(add, "add can't be null or empty"); 27 | add.forEach(this::add); 28 | } 29 | 30 | @Override 31 | public void add(PipelineProvider provider) 32 | { 33 | Validate.notNull(provider, "provider can't be null"); 34 | providers.add(provider); 35 | } 36 | 37 | @Override 38 | public void remove(PipelineProvider provider) 39 | { 40 | providers.remove(provider); 41 | } 42 | 43 | @Override 44 | public void call(T object) 45 | { 46 | providers.forEach(provider -> provider.pipeline(object)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/player/Connectable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.player; 8 | 9 | /** 10 | * Represents an object which can be connected to a given server 11 | * 12 | * @author Creart 13 | */ 14 | public interface Connectable { 15 | 16 | /** 17 | * Connects to the given Minecraft server 18 | * 19 | * @param serverName server's name 20 | */ 21 | void connect(String serverName); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/player/Contactable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.player; 8 | 9 | /** 10 | * Represents one or more users which can be contacted 11 | * 12 | * @author Creart 13 | */ 14 | public interface Contactable { 15 | 16 | /** 17 | * Sends the messagePath associated to the given path followed with all the replace arguments. 18 | *

19 | * Example: 20 | * 21 | * contactableInstance.sendMessage("friend_accepted;" + granter.getName()", MessageType.CHAT); 22 | * 23 | * 24 | * @param messagePath the path to the message to send 25 | * @param type the messagePath's type 26 | */ 27 | void sendMessage(String messagePath, MessageType type); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/player/MessageType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.player; 8 | 9 | /** 10 | * Represents different ways to contact players 11 | * 12 | * @author Creart 13 | */ 14 | public enum MessageType { 15 | 16 | ACTION_BAR((byte) 0), 17 | CHAT_MESSAGE((byte) 1), 18 | /** 19 | * Actually a subtitle 20 | */ 21 | TITLE((byte) 2); 22 | 23 | private byte id; 24 | 25 | MessageType(byte id) 26 | { 27 | this.id = id; 28 | } 29 | 30 | public byte getId() 31 | { 32 | return id; 33 | } 34 | 35 | /** 36 | * Returns the message type associated to the given id 37 | * 38 | * @param id the given id 39 | * @return the message type associated to the given id 40 | */ 41 | public static MessageType fromId(byte id) 42 | { 43 | for (MessageType type : values()) 44 | if (type.id == id) 45 | return type; 46 | 47 | return null; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/player/Party.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.player; 8 | 9 | import fr.creart.gamestack.common.Commons; 10 | import fr.creart.gamestack.common.protocol.ProtocolWrap; 11 | import fr.creart.gamestack.common.protocol.packet.result.MessageResult; 12 | import fr.creart.gamestack.common.protocol.packet.result.PlayerTeleport; 13 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 14 | 15 | /** 16 | * @author Creart 17 | */ 18 | public class Party implements Queueable { 19 | 20 | private static final ByteArrayPacket TELEPORT_PACKET = ProtocolWrap.getPacketById(ProtocolWrap.PLAYER_TELEPORT_PACKET_ID); 21 | private static final ByteArrayPacket MESSAGE_PACKET = ProtocolWrap.getPacketById(ProtocolWrap.MESSAGE_PACKET_ID); 22 | 23 | private final Player leader; 24 | private Player[] players; 25 | 26 | public Party(Player leader, Player[] players) 27 | { 28 | this.leader = leader; 29 | this.players = players; 30 | } 31 | 32 | @Override 33 | public void connect(String serverName) 34 | { 35 | Commons.getInstance().getMessageBroker().publish(TELEPORT_PACKET, new PlayerTeleport(serverName, getAllUUIDs())); 36 | } 37 | 38 | @Override 39 | public void sendMessage(String path, MessageType type) 40 | { 41 | Commons.getInstance().getMessageBroker().publish(MESSAGE_PACKET, new MessageResult(type, path, getAllUUIDs())); 42 | } 43 | 44 | @Override 45 | public byte getWeight() 46 | { 47 | // 1 corresponds to the leader 48 | return (byte) (1 + players.length); 49 | } 50 | 51 | @Override 52 | public byte getPriority() 53 | { 54 | return leader.getPriority(); 55 | } 56 | 57 | @Override 58 | public int hashCode() 59 | { 60 | return leader.hashCode(); 61 | } 62 | 63 | public Player[] getPlayers() 64 | { 65 | return players; 66 | } 67 | 68 | public Player getLeader() 69 | { 70 | return leader; 71 | } 72 | 73 | private String[] getAllUUIDs() 74 | { 75 | String[] uuids = new String[players.length + 1]; 76 | uuids[0] = leader.getUniqueId(); 77 | for (int i = 0; i < players.length; i++) 78 | uuids[i + 1] = players[i].getUniqueId(); 79 | return uuids; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/player/Player.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.player; 8 | 9 | import com.google.common.base.Strings; 10 | import fr.creart.gamestack.common.Commons; 11 | import fr.creart.gamestack.common.log.CommonLogger; 12 | import fr.creart.gamestack.common.protocol.ProtocolWrap; 13 | import fr.creart.gamestack.common.protocol.packet.MessagePacket; 14 | import fr.creart.gamestack.common.protocol.packet.PlayerTeleportPacket; 15 | import fr.creart.gamestack.common.protocol.packet.result.MessageResult; 16 | import fr.creart.gamestack.common.protocol.packet.result.PlayerTeleport; 17 | 18 | /** 19 | * Represents a player connected to the network 20 | * 21 | * @author Creart 22 | */ 23 | public class Player implements Queueable { 24 | 25 | private static final PlayerTeleportPacket TELEPORT_PACKET = ProtocolWrap.getPacketById(ProtocolWrap.PLAYER_TELEPORT_PACKET_ID); 26 | private static final MessagePacket MESSAGE_PACKET = ProtocolWrap.getPacketById(ProtocolWrap.MESSAGE_PACKET_ID); 27 | 28 | private final String uuid; 29 | private final byte priority; 30 | 31 | public Player(String uuid, byte priority) 32 | { 33 | this.uuid = uuid; 34 | this.priority = priority; 35 | } 36 | 37 | /** 38 | * Returns player's uuid 39 | * 40 | * @return player's uuid 41 | */ 42 | public String getUniqueId() 43 | { 44 | return uuid; 45 | } 46 | 47 | @Override 48 | public byte getPriority() 49 | { 50 | return priority; 51 | } 52 | 53 | @Override 54 | public byte getWeight() 55 | { 56 | return 1; 57 | } 58 | 59 | @Override 60 | public void connect(String serverName) 61 | { 62 | if (Strings.isNullOrEmpty(serverName)) { 63 | CommonLogger.warn("Tried to teleport player (uuid=" + uuid + ") to an empty/null server name."); 64 | return; 65 | } 66 | 67 | Commons.getInstance().getMessageBroker().publish(TELEPORT_PACKET, new PlayerTeleport(serverName, uuid)); 68 | } 69 | 70 | @Override 71 | public void sendMessage(String messagePath, MessageType type) 72 | { 73 | Commons.getInstance().getMessageBroker().publish(MESSAGE_PACKET, new MessageResult(type, messagePath, getUniqueId())); 74 | } 75 | 76 | @Override 77 | public String toString() 78 | { 79 | return "Player[uuid=" + uuid + "]"; 80 | } 81 | 82 | @Override 83 | public int hashCode() 84 | { 85 | return uuid.hashCode(); 86 | } 87 | 88 | @Override 89 | public boolean equals(Object obj) 90 | { 91 | return obj instanceof Player && hashCode() == obj.hashCode(); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/player/Queueable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.player; 8 | 9 | /** 10 | * Represents an object which can be enqueued in the player queues 11 | * 12 | * @author Creart 13 | */ 14 | public interface Queueable extends Connectable, Contactable { 15 | 16 | /** 17 | * Returns the "weight" of the queueable object. Which is 1 for each player, 18 | * so a party of 10 players has a weight of 10. 19 | * 20 | * @return the "weight" of the queueable object 21 | */ 22 | byte getWeight(); 23 | 24 | /** 25 | * Returns the priority of the current item. 26 | *

27 | * If it is a player, his priority is given; otherwise if it is a party, leader's priority is given. 28 | * 29 | * @return the priority of the current item 30 | */ 31 | byte getPriority(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/PacketListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol; 8 | 9 | /** 10 | * Represents a listener which listens for a packet. 11 | * 12 | * @param the type of data result 13 | * @author Creart 14 | */ 15 | @FunctionalInterface 16 | public interface PacketListener { 17 | 18 | /** 19 | * Called as an event when a packet is received for which the current listener has been registered. 20 | * 21 | * @param packetId Packet's id 22 | * @param result Received data 23 | */ 24 | void handlePacket(int packetId, T result); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/ProtocolWrap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol; 8 | 9 | import fr.creart.gamestack.common.log.CommonLogger; 10 | import fr.creart.gamestack.common.protocol.packet.EnqueuePacket; 11 | import fr.creart.gamestack.common.protocol.packet.HostUpdatePacket; 12 | import fr.creart.gamestack.common.protocol.packet.MessagePacket; 13 | import fr.creart.gamestack.common.protocol.packet.MetricPacket; 14 | import fr.creart.gamestack.common.protocol.packet.MinecraftServerStatusPacket; 15 | import fr.creart.gamestack.common.protocol.packet.PlayerTeleportPacket; 16 | import fr.creart.gamestack.common.protocol.packet.PullQueuePacket; 17 | import fr.creart.protocolt.ProtoColt; 18 | import fr.creart.protocolt.Protocol; 19 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 20 | 21 | /** 22 | * Wraps {@link fr.creart.protocolt.ProtoColt} library. 23 | * 24 | * @author Creart 25 | */ 26 | public final class ProtocolWrap { 27 | 28 | public static final short HOST_UPDATE_PACKET_ID = 0x01; 29 | public static final short MINECRAFT_SERVER_STATUS_PACKET_ID = 0x02; 30 | public static final short METRIC_PACKET_ID = 0x03; 31 | public static final short PLAYER_TELEPORT_PACKET_ID = 0x04; 32 | public static final short ENQUEUE_PACKET_ID = 0x05; 33 | public static final short MESSAGE_PACKET_ID = 0x06; 34 | public static final short PULL_QUEUE_PACKET_ID = 0x07; 35 | 36 | private static Protocol protocol; 37 | 38 | static { 39 | ProtoColt.configure(true); 40 | ProtoColt proto = ProtoColt.getInstance(); 41 | protocol = proto.getOrCreateProtocol("gamestack"); 42 | 43 | // declare packets 44 | 45 | try { 46 | protocol.declarePacket(new HostUpdatePacket(HOST_UPDATE_PACKET_ID)); 47 | protocol.declarePacket(new MinecraftServerStatusPacket(MINECRAFT_SERVER_STATUS_PACKET_ID)); 48 | protocol.declarePacket(new MetricPacket(METRIC_PACKET_ID)); 49 | protocol.declarePacket(new PlayerTeleportPacket(PLAYER_TELEPORT_PACKET_ID)); 50 | protocol.declarePacket(new EnqueuePacket(ENQUEUE_PACKET_ID)); 51 | protocol.declarePacket(new MessagePacket(MESSAGE_PACKET_ID)); 52 | protocol.declarePacket(new PullQueuePacket(PULL_QUEUE_PACKET_ID)); 53 | } catch (Exception e) { 54 | CommonLogger.error("Could not declare a packet.", e); 55 | } 56 | } 57 | 58 | private ProtocolWrap() 59 | { 60 | // no instance 61 | } 62 | 63 | /** 64 | * Returns the packet associated to the id 65 | * 66 | * @param id id of the packet 67 | * @return the packet associated to the id 68 | */ 69 | @SuppressWarnings("unchecked") 70 | public static > T getPacketById(int id) 71 | { 72 | return (T) protocol.getPacketById(id); 73 | } 74 | 75 | /** 76 | * Returns true if the packet has been declared 77 | * 78 | * @param packetId packet's id 79 | * @return true if the packet has been declared 80 | */ 81 | public static boolean hasPacket(int packetId) 82 | { 83 | return protocol.getPacketById(packetId) != null; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/EnqueuePacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import fr.creart.gamestack.common.protocol.packet.result.EnqueueData; 10 | import fr.creart.protocolt.bytestreams.ByteArrayDataSource; 11 | import fr.creart.protocolt.bytestreams.ByteArrayDataWriter; 12 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 13 | 14 | /** 15 | * This packet is sent when a queueable item (composed of its players which are represented by their UUID) 16 | * should be enqueued to the given {@link fr.creart.gamestack.common.game.GameMap}. 17 | *

18 | * The player UUIDs are written in a String and separated by a semi-colon. 19 | * 20 | * @author Creart 21 | */ 22 | public class EnqueuePacket extends ByteArrayPacket { 23 | 24 | public EnqueuePacket(int id) 25 | { 26 | super(id); 27 | } 28 | 29 | @Override 30 | public EnqueueData read(ByteArrayDataSource src) 31 | { 32 | return new EnqueueData(Util.getUUIDs(src.readString()), src.readByte(), null); 33 | /*TODO: Create a manager from which it will be possible to retrieve the demanded map*/ 34 | } 35 | 36 | @Override 37 | public void write(ByteArrayDataWriter writer, EnqueueData data) 38 | { 39 | writer.write(Util.toStringFormat(data.getPlayerUUIDs())); 40 | writer.write(data.getPriority()); 41 | writer.write(data.getMap().getGame().getId()); 42 | writer.write(data.getMap().getId()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/HostUpdatePacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import fr.creart.gamestack.common.protocol.packet.result.HostUpdate; 10 | import fr.creart.protocolt.bytestreams.ByteArrayDataSource; 11 | import fr.creart.protocolt.bytestreams.ByteArrayDataWriter; 12 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 13 | 14 | /** 15 | * Packet sent every second by a host instance 16 | * 17 | * @author Creart 18 | */ 19 | public class HostUpdatePacket extends ByteArrayPacket { 20 | 21 | public HostUpdatePacket(int id) 22 | { 23 | super(id); 24 | } 25 | 26 | @Override 27 | public HostUpdate read(ByteArrayDataSource source) 28 | { 29 | return new HostUpdate(source.readString(), source.readFloat(), source.readFloat()); 30 | } 31 | 32 | @Override 33 | public void write(ByteArrayDataWriter writer, HostUpdate update) 34 | { 35 | writer.write(update.getAddress()); 36 | writer.write(update.getCapacity()); 37 | writer.write(update.getUsedCapacity()); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/MessagePacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import fr.creart.gamestack.common.player.MessageType; 10 | import fr.creart.gamestack.common.protocol.packet.result.MessageResult; 11 | import fr.creart.protocolt.bytestreams.ByteArrayDataSource; 12 | import fr.creart.protocolt.bytestreams.ByteArrayDataWriter; 13 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 14 | 15 | /** 16 | * Packet handled by the BungeeCord instances which allows to send a message to one or more players. 17 | * 18 | * @author Creart 19 | */ 20 | public class MessagePacket extends ByteArrayPacket { 21 | 22 | public MessagePacket(int id) 23 | { 24 | super(id); 25 | } 26 | 27 | @Override 28 | public MessageResult read(ByteArrayDataSource src) 29 | { 30 | return new MessageResult(MessageType.fromId(src.readByte()), src.readString(), Util.getUUIDs(src.readString())); 31 | } 32 | 33 | @Override 34 | public void write(ByteArrayDataWriter writer, MessageResult result) 35 | { 36 | writer.write(result.getType().getId()); 37 | writer.write(Util.toStringFormat(result.getPlayerUUIDs())); 38 | writer.write(result.getMessage()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/MetricPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import fr.creart.gamestack.common.Commons; 10 | import fr.creart.gamestack.common.metric.Metric; 11 | import fr.creart.gamestack.common.misc.JsonUtil; 12 | import fr.creart.protocolt.bytestreams.ByteArrayDataSource; 13 | import fr.creart.protocolt.bytestreams.ByteArrayDataWriter; 14 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 15 | 16 | /** 17 | * Metric packet propagated on the network 18 | * 19 | * @author Creart 20 | */ 21 | public class MetricPacket extends ByteArrayPacket { 22 | 23 | public MetricPacket(int id) 24 | { 25 | super(id); 26 | } 27 | 28 | @Override 29 | public Metric read(ByteArrayDataSource src) 30 | { 31 | return JsonUtil.fromJson(Commons.getInstance().getMetricsManager().getMetric(src.readString()), src.readString()); 32 | } 33 | 34 | @Override 35 | public void write(ByteArrayDataWriter writer, Metric metric) 36 | { 37 | writer.write(Commons.getInstance().getMetricsManager().getMetricName(metric.getClass())); 38 | writer.write(JsonUtil.toJson(metric)); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/MinecraftServerStatusPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import fr.creart.gamestack.common.game.GameStatus; 10 | import fr.creart.gamestack.common.log.CommonLogger; 11 | import fr.creart.gamestack.common.protocol.packet.result.KeepAliveStatus; 12 | import fr.creart.gamestack.common.protocol.packet.result.MinecraftServerUpdate; 13 | import fr.creart.protocolt.bytestreams.ByteArrayDataSource; 14 | import fr.creart.protocolt.bytestreams.ByteArrayDataWriter; 15 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 16 | 17 | /** 18 | * Packet sent every seconds which can be sent for adding a Minecraft server, 19 | * updating a Minecraft server or removing a Minecraft server. 20 | * 21 | * @author Creart 22 | */ 23 | public class MinecraftServerStatusPacket extends ByteArrayPacket { 24 | 25 | public MinecraftServerStatusPacket(int id) 26 | { 27 | super(id); 28 | } 29 | 30 | @Override 31 | public MinecraftServerUpdate read(ByteArrayDataSource source) 32 | { 33 | byte statusId = source.readByte(); 34 | KeepAliveStatus status = KeepAliveStatus.getById(statusId); 35 | 36 | if (status == null) { 37 | CommonLogger.error("Received a Minecraft server status packet with an unrecognized mode (" + statusId + ")!"); 38 | return null; 39 | } 40 | 41 | MinecraftServerUpdate update = 42 | new MinecraftServerUpdate(source.readString(), source.readInt(), source.readInt(), status, GameStatus.getById(source.readByte())); 43 | 44 | if (status == KeepAliveStatus.ADD || status == KeepAliveStatus.UPDATE) { 45 | update.setOnlinePlayers(source.readShort()); 46 | update.setMaxPlayers(source.readShort()); 47 | } 48 | 49 | return update; 50 | } 51 | 52 | @Override 53 | public void write(ByteArrayDataWriter writer, MinecraftServerUpdate data) 54 | { 55 | writer.write(data.getStatus().getId()); 56 | writer.write(data.getAddress()); 57 | writer.write(data.getGameId()); 58 | writer.write(data.getPort()); 59 | writer.write(data.getGameStatus().getId()); 60 | if (data.getStatus() == KeepAliveStatus.ADD || data.getStatus() == KeepAliveStatus.UPDATE) { 61 | writer.write(data.getOnlinePlayers()); 62 | writer.write(data.getMaxPlayers()); 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/PlayerTeleportPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import fr.creart.gamestack.common.protocol.packet.result.PlayerTeleport; 10 | import fr.creart.protocolt.bytestreams.ByteArrayDataSource; 11 | import fr.creart.protocolt.bytestreams.ByteArrayDataWriter; 12 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 13 | 14 | /** 15 | * Sent when a player needs to be teleported to a specific server 16 | * 17 | * @author Creart 18 | */ 19 | public class PlayerTeleportPacket extends ByteArrayPacket { 20 | 21 | public PlayerTeleportPacket(int id) 22 | { 23 | super(id); 24 | } 25 | 26 | @Override 27 | public PlayerTeleport read(ByteArrayDataSource source) 28 | { 29 | return new PlayerTeleport(source.readString(), Util.getUUIDs(source.readString())); 30 | } 31 | 32 | @Override 33 | public void write(ByteArrayDataWriter writer, PlayerTeleport teleport) 34 | { 35 | writer.write(teleport.getTargetServer()); 36 | writer.write(Util.toStringFormat(teleport.getPlayerUUIDs())); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/PullQueuePacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import fr.creart.gamestack.common.protocol.packet.result.PullQueueData; 10 | import fr.creart.protocolt.bytestreams.ByteArrayDataSource; 11 | import fr.creart.protocolt.bytestreams.ByteArrayDataWriter; 12 | import fr.creart.protocolt.bytestreams.ByteArrayPacket; 13 | 14 | /** 15 | * Packet sent by a BungeeCord instance when players should be removed from their queue. 16 | * Sent when: 17 | *

    18 | *
  • A player disconnects.
  • 19 | *
20 | *

21 | * If only one UUID is sent and the player is the leader, the whole party is removed; if he is not, only the given player will be removed. 22 | *

23 | * So, in order to remove a party, you can either send all the UUIDs, or only the leader's UUID. 24 | * 25 | * @author Creart 26 | */ 27 | public class PullQueuePacket extends ByteArrayPacket { 28 | 29 | public PullQueuePacket(int id) 30 | { 31 | super(id); 32 | } 33 | 34 | @Override 35 | public PullQueueData read(ByteArrayDataSource src) 36 | { 37 | return new PullQueueData(Util.getUUIDs(src.readString())); 38 | } 39 | 40 | @Override 41 | public void write(ByteArrayDataWriter writer, PullQueueData data) 42 | { 43 | writer.write(Util.toStringFormat(data.getPlayerUUIDs())); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet; 8 | 9 | import org.apache.commons.lang3.StringUtils; 10 | 11 | /** 12 | * @author Creart 13 | */ 14 | final class Util { 15 | 16 | private static final String UUID_SPLITTER = ";"; 17 | 18 | private Util() 19 | { 20 | // no instance 21 | } 22 | 23 | static String[] getUUIDs(String uuids) 24 | { 25 | return uuids.split(UUID_SPLITTER); 26 | } 27 | 28 | static String toStringFormat(String[] uuids) 29 | { 30 | return StringUtils.join(uuids, UUID_SPLITTER); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/EnqueueData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet.result; 8 | 9 | import fr.creart.gamestack.common.game.GameMap; 10 | import fr.creart.gamestack.common.protocol.packet.EnqueuePacket; 11 | 12 | /** 13 | * {@link EnqueuePacket}'s result. 14 | * 15 | * @author Creart 16 | */ 17 | public class EnqueueData extends MultiPlayerData { 18 | 19 | private final byte priority; 20 | private final GameMap map; 21 | 22 | public EnqueueData(String[] playerUUIDs, byte priority, GameMap map) 23 | { 24 | super(playerUUIDs); 25 | this.priority = priority; 26 | this.map = map; 27 | } 28 | 29 | /** 30 | * Returns the priority of the queueable item. If the item is a party 31 | * the priority is the leader's one 32 | * 33 | * @return the priority of the queueable item. 34 | */ 35 | public byte getPriority() 36 | { 37 | return priority; 38 | } 39 | 40 | /** 41 | * Returns the requested map. 42 | * 43 | * @return the requested map. 44 | */ 45 | public GameMap getMap() 46 | { 47 | return map; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/HostUpdate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.common.protocol.packet.result; 14 | 15 | import fr.creart.gamestack.common.protocol.packet.HostUpdatePacket; 16 | 17 | /** 18 | * Data class which contains information about a new server and represents an update (created on the reception of the 19 | * {@link HostUpdatePacket}). 20 | * 21 | * @author Creart 22 | */ 23 | public class HostUpdate extends HostedData { 24 | 25 | private final float capacity; 26 | private final float usedCapacity; 27 | 28 | /** 29 | * @param address server's address 30 | * @param capacity server's max capacity 31 | * @param usedCapacity server's used capacity 32 | */ 33 | public HostUpdate(String address, float capacity, float usedCapacity) 34 | { 35 | super(address); 36 | this.capacity = capacity; 37 | this.usedCapacity = usedCapacity; 38 | } 39 | 40 | public float getCapacity() 41 | { 42 | return capacity; 43 | } 44 | 45 | public float getUsedCapacity() 46 | { 47 | return usedCapacity; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/HostedData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.common.protocol.packet.result; 14 | 15 | /** 16 | * Represents data which is provided by a known host 17 | * 18 | * @author Creart 19 | */ 20 | public abstract class HostedData { 21 | 22 | private String address; 23 | 24 | /** 25 | * @param address host's address 26 | */ 27 | public HostedData(String address) 28 | { 29 | this.address = address; 30 | } 31 | 32 | /** 33 | * Returns server's address 34 | * 35 | * @return server's address 36 | */ 37 | public String getAddress() 38 | { 39 | return address; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/KeepAliveStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet.result; 8 | 9 | /** 10 | * Represents a status update 11 | * 12 | * @author Creart 13 | */ 14 | public enum KeepAliveStatus { 15 | 16 | ADD((byte) 0), 17 | UPDATE((byte) 1), 18 | DELETE((byte) 2); 19 | 20 | private final byte id; 21 | 22 | KeepAliveStatus(byte id) 23 | { 24 | this.id = id; 25 | } 26 | 27 | public byte getId() 28 | { 29 | return id; 30 | } 31 | 32 | /** 33 | * Returns the status associated to the given id 34 | * 35 | * @param id status' id 36 | * @return the status associated to the given id 37 | */ 38 | public static KeepAliveStatus getById(int id) 39 | { 40 | for (KeepAliveStatus status : values()) 41 | if (status.id == id) 42 | return status; 43 | return null; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/MessageResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet.result; 8 | 9 | import fr.creart.gamestack.common.player.MessageType; 10 | import fr.creart.gamestack.common.protocol.packet.MessagePacket; 11 | 12 | /** 13 | * {@link MessagePacket}'s result. 14 | * 15 | * @author Creart 16 | */ 17 | public class MessageResult extends MultiPlayerData { 18 | 19 | private final String message; 20 | private final MessageType type; 21 | 22 | public MessageResult(MessageType type, String message, String... playerUUIDs) 23 | { 24 | super(playerUUIDs); 25 | this.type = type; 26 | this.message = message; 27 | } 28 | 29 | public MessageType getType() 30 | { 31 | return type; 32 | } 33 | 34 | public String getMessage() 35 | { 36 | return message; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/MinecraftServerUpdate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet.result; 8 | 9 | import fr.creart.gamestack.common.game.GameStatus; 10 | 11 | /** 12 | * Represents a Minecraft server update, which can be an adding, update or deletion. 13 | * 14 | * @author Creart 15 | */ 16 | public class MinecraftServerUpdate extends SocketHostData { 17 | 18 | private final KeepAliveStatus status; 19 | private final GameStatus gameStatus; 20 | private final int gameId; 21 | private short onlinePlayers; 22 | private short maxPlayers; 23 | 24 | /** 25 | * @param address server's address 26 | * @param port server's port 27 | * @param status server's status 28 | */ 29 | public MinecraftServerUpdate(String address, int gameId, int port, KeepAliveStatus status, GameStatus gameStatus) 30 | { 31 | super(address, port); 32 | this.gameId = gameId; 33 | this.status = status; 34 | this.gameStatus = gameStatus; 35 | } 36 | 37 | public void setOnlinePlayers(short onlinePlayers) 38 | { 39 | this.onlinePlayers = onlinePlayers; 40 | } 41 | 42 | public void setMaxPlayers(short maxPlayers) 43 | { 44 | this.maxPlayers = maxPlayers; 45 | } 46 | 47 | public int getGameId() 48 | { 49 | return gameId; 50 | } 51 | 52 | public KeepAliveStatus getStatus() 53 | { 54 | return status; 55 | } 56 | 57 | public GameStatus getGameStatus() 58 | { 59 | return gameStatus; 60 | } 61 | 62 | public short getOnlinePlayers() 63 | { 64 | return onlinePlayers; 65 | } 66 | 67 | public short getMaxPlayers() 68 | { 69 | return maxPlayers; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/MultiPlayerData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet.result; 8 | 9 | /** 10 | * Represents data which is bound to one or more players 11 | * 12 | * @author Creart 13 | */ 14 | public abstract class MultiPlayerData { 15 | 16 | protected final String[] playerUUIDs; 17 | 18 | public MultiPlayerData(String[] playerUUIDs) 19 | { 20 | this.playerUUIDs = playerUUIDs; 21 | } 22 | 23 | public String[] getPlayerUUIDs() 24 | { 25 | return playerUUIDs; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/PlayerTeleport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet.result; 8 | 9 | /** 10 | * {@link fr.creart.gamestack.common.protocol.packet.PlayerTeleportPacket}'s result. 11 | * 12 | * @author Creart 13 | */ 14 | public class PlayerTeleport extends MultiPlayerData { 15 | 16 | private final String targetServer; 17 | 18 | public PlayerTeleport(String targetServer, String... playerUUIDs) 19 | { 20 | super(playerUUIDs); 21 | this.targetServer = targetServer; 22 | } 23 | 24 | /** 25 | * Returns the name of the server to which the player has to be teleported 26 | * 27 | * @return the name of the server to which the player has to be teleported 28 | */ 29 | public String getTargetServer() 30 | { 31 | return targetServer; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/PullQueueData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.protocol.packet.result; 8 | 9 | /** 10 | * @author Creart 11 | */ 12 | public class PullQueueData extends MultiPlayerData { 13 | 14 | public PullQueueData(String[] playerUUIDs) 15 | { 16 | super(playerUUIDs); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/protocol/packet/result/SocketHostData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.common.protocol.packet.result; 14 | 15 | import java.net.InetSocketAddress; 16 | 17 | /** 18 | * Represents data provided by a socket (with a known host and port) 19 | * 20 | * @author Creart 21 | */ 22 | public abstract class SocketHostData extends HostedData { 23 | 24 | private final int port; 25 | 26 | /** 27 | * @param address socket's address 28 | * @param port socket's port 29 | */ 30 | public SocketHostData(String address, int port) 31 | { 32 | super(address); 33 | this.port = port; 34 | } 35 | 36 | public int getPort() 37 | { 38 | return port; 39 | } 40 | 41 | public InetSocketAddress getSocketAddress() 42 | { 43 | return new InetSocketAddress(getAddress(), port); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/text/Translator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.text; 8 | 9 | import fr.creart.gamestack.common.io.FileUtil; 10 | import fr.creart.gamestack.common.misc.Initialisable; 11 | import java.io.FileInputStream; 12 | import java.io.IOException; 13 | import java.text.MessageFormat; 14 | import java.util.PropertyResourceBundle; 15 | import java.util.ResourceBundle; 16 | import org.apache.log4j.Logger; 17 | 18 | /** 19 | * Util class which allows to obtain translations from the "messages.properties" file and replace arguments ("{\d}") 20 | * The translations are user-related. 21 | * 22 | * @author Creart 23 | */ 24 | public class Translator implements Initialisable { 25 | 26 | private static final Logger LOGGER = Logger.getLogger(Translator.class); 27 | 28 | private String file; 29 | private boolean initialised; 30 | private ResourceBundle resourceBundle; 31 | 32 | public Translator(String file) 33 | { 34 | this.file = file; 35 | } 36 | 37 | /** 38 | * Initialises the translator. 39 | */ 40 | @Override 41 | public void initialise() 42 | { 43 | if (initialised) 44 | return; 45 | 46 | try { 47 | initialise(false); 48 | } catch (Exception e) { 49 | LOGGER.error(String.format("Could not load %s file. Trying again with another way...", file)); 50 | try { 51 | initialise(true); 52 | } catch (Exception e1) { 53 | LOGGER.error(String.format("Could not load %s file!", file), e1); 54 | return; 55 | } 56 | } 57 | 58 | LOGGER.info("Successfully loaded messages.properties file."); 59 | initialised = true; 60 | } 61 | 62 | /** 63 | * Returns the translated text (all arguments replaced by the objects). 64 | * 65 | * @param path String's path 66 | * @param objects Objects to replace arguments 67 | * @return the translated text (all arguments replaced by the objects). 68 | */ 69 | public String translate(String path, Object... objects) 70 | { 71 | String ret; 72 | 73 | try { 74 | ret = MessageFormat.format(resourceBundle.getString(path), objects); 75 | } catch (Exception e) { 76 | LOGGER.error(String.format("Could not get String %s in %s.", path, file), e); 77 | ret = "/!\\ translation missing '" + path + "' /!\\"; 78 | } 79 | 80 | return ret; 81 | } 82 | 83 | private void initialise(boolean retry) throws IOException 84 | { 85 | if (retry && !FileUtil.saveResource(file, file, true).isSuccess()) 86 | throw new IOException("Could not create messages.properties file."); 87 | 88 | FileInputStream in = new FileInputStream(file); 89 | resourceBundle = new PropertyResourceBundle(in); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/thread/ThreadsManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.thread; 8 | 9 | import com.google.common.util.concurrent.ThreadFactoryBuilder; 10 | import fr.creart.gamestack.common.log.CommonLogger; 11 | import fr.creart.gamestack.common.misc.Destroyable; 12 | import java.lang.Thread.UncaughtExceptionHandler; 13 | import java.util.concurrent.ThreadFactory; 14 | 15 | /** 16 | * @author Creart 17 | */ 18 | public final class ThreadsManager implements Destroyable, AutoCloseable { 19 | 20 | private static final ThreadGroup PARENT_GROUP = new ThreadGroup("GameStack"); 21 | 22 | private final ThreadGroup currentGroup; 23 | private boolean initialised; 24 | 25 | /** 26 | * @param softName current software's name 27 | */ 28 | public ThreadsManager(String softName) 29 | { 30 | currentGroup = new ThreadGroup(PARENT_GROUP, softName); 31 | } 32 | 33 | @Override 34 | public void close() throws Exception 35 | { 36 | destroy(); 37 | } 38 | 39 | @Override 40 | public void destroy() 41 | { 42 | if (!initialised) 43 | return; 44 | 45 | currentGroup.destroy(); 46 | PARENT_GROUP.destroy(); 47 | 48 | initialised = false; 49 | } 50 | 51 | /** 52 | * Returns a new thread group whose parent is the thread group of the soft. 53 | * 54 | * @param name Thread group's name 55 | * @return a new thread group whose parent is the thread group of the soft. 56 | */ 57 | public ThreadGroup newThreadGroup(String name) 58 | { 59 | return new ThreadGroup(currentGroup, name); 60 | } 61 | 62 | /** 63 | * Returns a new {@link ThreadFactory} with the precised thread group name. 64 | * 65 | * @param groupName Thread group's name 66 | * @return a new {@link ThreadFactory} with the precised thread group name. 67 | */ 68 | public ThreadFactory newThreadFactory(String groupName) 69 | { 70 | return newThreadFactory(newThreadGroup(groupName)); 71 | } 72 | 73 | /** 74 | * Returns a new {@link ThreadFactory} with the precised thread group. 75 | * 76 | * @param group Thread group's name 77 | * @return a new {@link ThreadFactory} with the precised thread group. 78 | */ 79 | public ThreadFactory newThreadFactory(ThreadGroup group) 80 | { 81 | return new ThreadFactoryBuilder() 82 | .setThreadFactory(runnable -> new Thread(group, runnable)) 83 | .setUncaughtExceptionHandler(new DefaultExceptionHandler()) 84 | .build(); 85 | } 86 | 87 | private class DefaultExceptionHandler implements UncaughtExceptionHandler { 88 | @Override 89 | public void uncaughtException(Thread t, Throwable e) 90 | { 91 | CommonLogger.error(String.format("An uncaught exception has been thrown (Thread=%s).", t.getName()), e); 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /common/src/main/java/fr/creart/gamestack/common/thread/ThreadsUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.thread; 8 | 9 | /** 10 | * Some threading utils 11 | * 12 | * @author Creart 13 | */ 14 | public class ThreadsUtil { 15 | 16 | private ThreadsUtil() 17 | { 18 | 19 | } 20 | 21 | /** 22 | * Sleeps the thread. If an {@link InterruptedException} is thrown it interrupts the thread. 23 | * 24 | * @param time Time to sleep 25 | */ 26 | public static void sleep(long time) 27 | { 28 | try { 29 | Thread.sleep(time); 30 | } catch (Exception e) { 31 | Thread.currentThread().interrupt(); 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /common/src/main/resources/network.properties: -------------------------------------------------------------------------------- 1 | # broker 2 | broker.system=rabbitmq 3 | broker.host=192.168.99.100 4 | broker.port=32770 5 | broker.virtual_host="" 6 | broker.username=root 7 | broker.password=root 8 | # database 9 | database.system=mariadb 10 | database.host=192.168.99.100 11 | database.port=32769 12 | database.username=root 13 | database.password=root 14 | database.db=gamestack 15 | -------------------------------------------------------------------------------- /common/src/test/java/fr/creart/gamestack/common/test/DecimalsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.test; 8 | 9 | import fr.creart.gamestack.common.lang.Decimals; 10 | import org.junit.Assert; 11 | import org.junit.Test; 12 | 13 | /** 14 | * @author Creart 15 | */ 16 | public class DecimalsTest { 17 | 18 | @Test 19 | public void firstDecimals() 20 | { 21 | Assert.assertEquals("1.7", Decimals.firstDecimals(1.6565655, 1)); 22 | Assert.assertEquals("1.56", Decimals.firstDecimals(1.555555, 2)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /common/src/test/java/fr/creart/gamestack/common/test/FilesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.test; 8 | 9 | import fr.creart.gamestack.common.io.FileUtil; 10 | import java.io.File; 11 | import org.junit.Assert; 12 | import org.junit.Test; 13 | 14 | /** 15 | * @author Creart 16 | */ 17 | public class FilesTest { 18 | 19 | @Test 20 | public void cleanNameTest() 21 | { 22 | 23 | File file = new File("pom.xml"); 24 | Assert.assertEquals("pom", FileUtil.getFileCleanName(file)); 25 | 26 | } 27 | 28 | @Test 29 | public void fileExtensionTest() 30 | { 31 | 32 | File file = new File("pom.xml"); 33 | Assert.assertEquals("xml", FileUtil.getFileExtension(file)); 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /common/src/test/java/fr/creart/gamestack/common/test/ValidationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.common.test; 8 | 9 | import fr.creart.gamestack.common.lang.Validation; 10 | import fr.creart.gamestack.common.lang.Validation.Failure; 11 | import fr.creart.gamestack.common.lang.Validation.Success; 12 | import org.junit.Assert; 13 | import org.junit.Test; 14 | 15 | /** 16 | * @author Creart 17 | */ 18 | public class ValidationTest { 19 | 20 | static Validation toInteger(String string) 21 | { 22 | try { 23 | return new Success<>(Integer.valueOf(string)); 24 | } catch (Exception e) { 25 | return new Failure<>(e); 26 | } 27 | } 28 | 29 | @Test 30 | public void testValidation() 31 | { 32 | Assert.assertTrue(!toInteger("aI350").isSuccess()); 33 | Assert.assertTrue(toInteger("123").isSuccess()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /netty-util/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | all 7 | fr.creart.gamestack 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | netty-util 13 | 14 | 15 | 16 | io.netty 17 | netty-all 18 | 4.1.6.Final 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /netty-util/src/main/java/fr/creart/gamestack/netty/NettyUtil.java: -------------------------------------------------------------------------------- 1 | package fr.creart.gamestack.netty; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.EventLoopGroup; 5 | import io.netty.channel.epoll.Epoll; 6 | import io.netty.channel.epoll.EpollEventLoopGroup; 7 | import io.netty.channel.nio.NioEventLoopGroup; 8 | import java.nio.charset.StandardCharsets; 9 | import java.util.concurrent.ThreadFactory; 10 | 11 | /** 12 | * @author Creart 13 | */ 14 | public class NettyUtil { 15 | 16 | private NettyUtil() 17 | { 18 | // no instance 19 | } 20 | 21 | /** 22 | * Creates an {@link EpollEventLoopGroup} if {@link Epoll} is available, 23 | * otherwise creates a {@link NioEventLoopGroup} 24 | * 25 | * @param threads number of threads 26 | * @param group the thread group 27 | * @return a new {@link EpollEventLoopGroup} or {@link NioEventLoopGroup} 28 | */ 29 | public static EventLoopGroup createEventLoopGroup(int threads, ThreadGroup group) 30 | { 31 | ThreadFactory factory = (runnable) -> new Thread(group, runnable); 32 | return Epoll.isAvailable() ? new EpollEventLoopGroup(threads, factory) : new NioEventLoopGroup(threads, factory); 33 | } 34 | 35 | /** 36 | * Reads a String from the given {@link ByteBuf} 37 | * 38 | * @param buffer the buffer 39 | * @return a String read from the given {@link ByteBuf} 40 | */ 41 | public static String readString(ByteBuf buffer) 42 | { 43 | if (buffer == null) 44 | throw new IllegalArgumentException("buffer cannot be null"); 45 | if (!buffer.isReadable()) 46 | throw new IllegalArgumentException("buffer has to be readable"); 47 | 48 | byte[] b = new byte[buffer.readInt()]; 49 | buffer.readBytes(b); 50 | return new String(b, StandardCharsets.UTF_8); 51 | } 52 | 53 | /** 54 | * Writes a String to the given {@link ByteBuf} 55 | * 56 | * @param buffer the buffer 57 | * @param string the string to write 58 | */ 59 | public static void writeString(ByteBuf buffer, String string) 60 | { 61 | if (buffer == null) 62 | throw new IllegalArgumentException("buffer cannot be null"); 63 | if (!buffer.isWritable()) 64 | throw new IllegalArgumentException("buffer has to be writable"); 65 | 66 | buffer.writeInt(string.length()); 67 | buffer.writeBytes(string.getBytes(StandardCharsets.UTF_8)); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /netty-util/src/main/java/fr/creart/gamestack/netty/protocol/SimplePacket.java: -------------------------------------------------------------------------------- 1 | package fr.creart.gamestack.netty.protocol; 2 | 3 | /** 4 | * Represents a simple packet, with an id and data written in a String 5 | * 6 | * @author Creart 7 | */ 8 | public class SimplePacket { 9 | 10 | private final short id; 11 | private final String data; 12 | 13 | /** 14 | * Default constructor 15 | * 16 | * @param id packet's id 17 | * @param data packet's data 18 | */ 19 | public SimplePacket(short id, String data) 20 | { 21 | this.id = id; 22 | this.data = data; 23 | } 24 | 25 | /** 26 | * Returns packet's id 27 | * 28 | * @return packet's id 29 | */ 30 | public short getId() 31 | { 32 | return id; 33 | } 34 | 35 | /** 36 | * Returns packet's data 37 | * 38 | * @return packet's data 39 | */ 40 | public String getData() 41 | { 42 | return data; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /netty-util/src/main/java/fr/creart/gamestack/netty/protocol/SimplePacketDecoder.java: -------------------------------------------------------------------------------- 1 | package fr.creart.gamestack.netty.protocol; 2 | 3 | import fr.creart.gamestack.netty.NettyUtil; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.ByteToMessageDecoder; 7 | import java.util.List; 8 | 9 | /** 10 | * Decodes {@link SimplePacket}s for Netty 11 | * 12 | * @author Creart 13 | */ 14 | public class SimplePacketDecoder extends ByteToMessageDecoder { 15 | 16 | @Override 17 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception 18 | { 19 | out.add(new SimplePacket(in.readShort(), NettyUtil.readString(in))); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /netty-util/src/main/java/fr/creart/gamestack/netty/protocol/SimplePacketEncoder.java: -------------------------------------------------------------------------------- 1 | package fr.creart.gamestack.netty.protocol; 2 | 3 | import fr.creart.gamestack.netty.NettyUtil; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.MessageToByteEncoder; 7 | 8 | /** 9 | * Encodes {@link SimplePacket}s for Netty 10 | * 11 | * @author Creart 12 | */ 13 | public class SimplePacketEncoder extends MessageToByteEncoder { 14 | 15 | @Override 16 | protected void encode(ChannelHandlerContext ctx, SimplePacket msg, ByteBuf out) throws Exception 17 | { 18 | out.writeShort(msg.getId()); 19 | NettyUtil.writeString(out, msg.getData()); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | fr.creart.gamestack 8 | all 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 3.5.1 18 | 19 | 1.8 20 | 1.8 21 | 22 | 23 | 24 | maven-assembly-plugin 25 | 26 | 27 | package 28 | 29 | single 30 | 31 | 32 | 33 | 34 | 35 | jar-with-dependencies 36 | 37 | 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-javadoc-plugin 42 | 2.10.4 43 | 44 | 45 | 46 | 47 | 48 | api 49 | bukkit 50 | bungee 51 | client 52 | common 53 | server 54 | netty-util 55 | 56 | 57 | -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | Where am I? 2 | -------- 3 | This is the server part of the GameStack project. -------------------------------------------------------------------------------- /server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | all 7 | fr.creart.gamestack 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | server 13 | 14 | 15 | 16 | fr.creart.gamestack 17 | common 18 | 1.0-SNAPSHOT 19 | 20 | 21 | fr.creart.gamestack 22 | netty-util 23 | 1.0-SNAPSHOT 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/Main.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server; 8 | 9 | import com.google.common.base.Strings; 10 | import fr.creart.gamestack.common.app.Application; 11 | import fr.creart.gamestack.common.conf.Configuration; 12 | import fr.creart.gamestack.common.conf.ConfigurationLoadException; 13 | import fr.creart.gamestack.common.conf.PropertiesConfiguration; 14 | import fr.creart.gamestack.common.io.FileUtil; 15 | import fr.creart.gamestack.common.lang.Validation; 16 | import fr.creart.gamestack.common.log.CommonLogger; 17 | import fr.creart.gamestack.server.command.CommandsManager; 18 | import java.io.BufferedReader; 19 | import java.io.File; 20 | import java.io.InputStreamReader; 21 | 22 | /** 23 | * @author Creart 24 | */ 25 | public class Main extends Application { 26 | 27 | private static final String CONFIGURATION_FILE = "gamestack.properties"; 28 | private static final String NETWORK_CONFIGURATION_FILE = "network.properties"; 29 | 30 | public static void main(String[] args) 31 | { 32 | new Main().startup("GameStack Server", "Server"); 33 | } 34 | 35 | @Override 36 | protected void load() throws Exception 37 | { 38 | Configuration configuration = loadConfiguration(CONFIGURATION_FILE, CONFIGURATION_FILE); 39 | 40 | if (configuration == null) 41 | throw new ConfigurationLoadException("Could not configuration file (" + CONFIGURATION_FILE + ")!"); 42 | 43 | Configuration networkConf = loadConfiguration(NETWORK_CONFIGURATION_FILE, NETWORK_CONFIGURATION_FILE); 44 | 45 | if (networkConf == null) 46 | throw new ConfigurationLoadException("Could not configuration file (" + NETWORK_CONFIGURATION_FILE + ")!"); 47 | 48 | configuration.initialise(); 49 | networkConf.initialise(); 50 | 51 | StackServer server = StackServer.getInstance(); 52 | server.setNetworkConfiguration(networkConf); 53 | server.initialise(); 54 | } 55 | 56 | @Override 57 | public void run() throws Exception 58 | { 59 | StackServer server = StackServer.getInstance(); 60 | // listen commands 61 | CommandsManager instance = CommandsManager.getInstance(); 62 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 63 | while (server.isRunning()) { 64 | // this is going to change because when the server is not running anymore, it has to wait for a line to exit 65 | String line; 66 | try { 67 | line = reader.readLine(); 68 | } catch (Exception e) { 69 | continue; // ignore 70 | } 71 | 72 | if (!Strings.isNullOrEmpty(line)) 73 | instance.executeCommand(line, null); 74 | } 75 | reader.close(); 76 | StackServer.getInstance().stop(); 77 | } 78 | 79 | private static Configuration loadConfiguration(String fileName, String destination) 80 | { 81 | // read the configuration file. 82 | Validation saveValidation = FileUtil.saveResource(fileName, destination, false); 83 | 84 | if (saveValidation.isSuccess()) { 85 | CommonLogger.info("Successfully loaded configuration file (" + fileName + ")."); 86 | return new PropertiesConfiguration(saveValidation.toOptional().get()); 87 | } 88 | 89 | return null; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/command/Command.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.server.command; 14 | 15 | import java.util.Collection; 16 | 17 | /** 18 | * Represents a command which can be executed from the console. 19 | * 20 | * @author Creart 21 | */ 22 | public abstract class Command { 23 | 24 | private final String label; 25 | private final String[] aliases; 26 | private final String help; 27 | 28 | /** 29 | * Default constructor 30 | * 31 | * @param label Command's label (its name) 32 | * @param aliases Command's aliases (other names) 33 | */ 34 | public Command(String label, String help, String... aliases) 35 | { 36 | this.label = label; 37 | this.help = help; 38 | this.aliases = aliases; 39 | } 40 | 41 | /** 42 | * Default constructor "helper" 43 | * 44 | * @param label Command's label (its name) 45 | * @param aliases Command's aliases (other names) 46 | */ 47 | public Command(String label, String help, Collection aliases) 48 | { 49 | this(label, help, (String[]) aliases.toArray()); 50 | } 51 | 52 | /** 53 | * Called on the command execution. 54 | * 55 | * @param args Provided arguments 56 | */ 57 | public abstract void execute(CommandSender sender, String[] args); 58 | 59 | /** 60 | * Returns command's label 61 | * 62 | * @return command's label 63 | */ 64 | String getLabel() 65 | { 66 | return label; 67 | } 68 | 69 | /** 70 | * Returns command's aliases 71 | * 72 | * @return command's aliases 73 | */ 74 | String[] getAliases() 75 | { 76 | return aliases; 77 | } 78 | 79 | /** 80 | * Returns command's help 81 | * 82 | * @return command's help 83 | */ 84 | String getHelp() 85 | { 86 | return help; 87 | } 88 | 89 | @Override 90 | public final boolean equals(Object obj) 91 | { 92 | return obj instanceof Command && label.equals(((Command) obj).label); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/command/CommandSender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.server.command; 14 | 15 | /** 16 | * Represents the executor a command 17 | * 18 | * @author Creart 19 | */ 20 | public interface CommandSender { 21 | 22 | /** 23 | * Sends a message to the sender 24 | * 25 | * @param message Message to send 26 | */ 27 | void sendMessage(String message); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/command/CommandsManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.server.command; 14 | 15 | import com.google.common.base.Preconditions; 16 | import com.google.common.base.Strings; 17 | import java.util.Collection; 18 | import java.util.HashMap; 19 | import java.util.HashSet; 20 | import java.util.Map; 21 | import java.util.Set; 22 | 23 | /** 24 | * Manages commands. 25 | * 26 | * @author Creart 27 | */ 28 | public final class CommandsManager { 29 | 30 | private static CommandsManager instance; 31 | 32 | // KEY = Command's label 33 | // VALUE = Command (execution) 34 | private Map commands = new HashMap<>(); 35 | 36 | private CommandsManager() 37 | { 38 | registerCommand(new HelpCommand()); 39 | } 40 | 41 | /** 42 | * Registers a new command 43 | * 44 | * @param command Command to register 45 | */ 46 | public void registerCommand(Command command) 47 | { 48 | Preconditions.checkNotNull(command, "command can't be null"); 49 | Preconditions.checkNotNull(Strings.emptyToNull(command.getLabel()), "command label can't be null or empty"); 50 | commands.put(command.getLabel().toLowerCase(), command); 51 | 52 | if (command.getAliases() == null || command.getAliases().length == 0) 53 | return; 54 | 55 | for (String alias : command.getAliases()) 56 | commands.put(alias.toLowerCase(), command); 57 | } 58 | 59 | /** 60 | * Function to call when the command is executed 61 | * 62 | * @param line Entered line by the user 63 | * @param sender Command's sender 64 | */ 65 | public void executeCommand(String line, CommandSender sender) 66 | { 67 | if (line == null || line.length() == 0) 68 | return; 69 | 70 | if (sender == null) 71 | sender = ConsoleSender.INSTANCE; 72 | 73 | String[] parts = line.split(" "); 74 | Command command = getCommandByName(parts[0]); 75 | 76 | if (command == null) { 77 | sender.sendMessage("Command " + parts[0] + " not found"); 78 | return; 79 | } 80 | 81 | String[] args = new String[]{}; 82 | System.arraycopy(parts, 1, args, 0, parts.length - 1); 83 | command.execute(sender, args); 84 | } 85 | 86 | /** 87 | * Returns registered commands 88 | * 89 | * @return registered commands 90 | */ 91 | Collection getCommands() 92 | { 93 | Set ret = new HashSet<>(); 94 | ret.addAll(commands.values()); 95 | return ret; 96 | } 97 | 98 | /** 99 | * Returns the command associated to the specified name 100 | * 101 | * @param name Name of the command 102 | * @return the command associated to the specified name 103 | */ 104 | Command getCommandByName(String name) 105 | { 106 | return commands.get(name.toLowerCase()); 107 | } 108 | 109 | /** 110 | * Returns the single instance of the commands manager 111 | * 112 | * @return the single instance of the commands manager 113 | */ 114 | public static CommandsManager getInstance() 115 | { 116 | if (instance == null) 117 | instance = new CommandsManager(); 118 | return instance; 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/command/ConsoleSender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.server.command; 14 | 15 | import com.google.common.base.Strings; 16 | 17 | /** 18 | * Represents a command executor from the console 19 | * 20 | * @author Creart 21 | */ 22 | public final class ConsoleSender implements CommandSender { 23 | 24 | static final CommandSender INSTANCE = new ConsoleSender(); 25 | 26 | private ConsoleSender() 27 | { 28 | 29 | } 30 | 31 | @Override 32 | public void sendMessage(String message) 33 | { 34 | if (Strings.isNullOrEmpty(message)) 35 | return; 36 | 37 | System.out.println("> ".concat(message)); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/command/HelpCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | package fr.creart.gamestack.server.command; 14 | 15 | import com.google.common.base.Strings; 16 | 17 | /** 18 | * Displays help for all commands or for the specified commands in the arguments. 19 | * 20 | * @author Creart 21 | */ 22 | class HelpCommand extends Command { 23 | 24 | private static final String FIRST_LINE = "All GameStack commands:\n"; 25 | 26 | HelpCommand() 27 | { 28 | super("help", "Displays help for one or all the commands", "?"); 29 | } 30 | 31 | @Override 32 | public void execute(CommandSender sender, String[] args) 33 | { 34 | if (args.length == 0) { 35 | StringBuilder builder = new StringBuilder(); 36 | builder.append(FIRST_LINE); 37 | CommandsManager.getInstance().getCommands().forEach(command -> 38 | builder.append("\t").append(command.getLabel()).append(": ").append(Strings.isNullOrEmpty(command.getHelp()) ? 39 | "No help found for this command" : 40 | command.getHelp()).append("\n")); 41 | sender.sendMessage(builder.toString()); 42 | } 43 | 44 | else { 45 | Command command = CommandsManager.getInstance().getCommandByName(args[0]); 46 | 47 | if (command == null) { 48 | sender.sendMessage("Help found for command \"" + args[0] + "\"."); 49 | return; 50 | } 51 | 52 | sender.sendMessage("Help for \"" + args[0] + "\" command: " + command.getHelp()); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/command/StopCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.command; 8 | 9 | import fr.creart.gamestack.server.StackServer; 10 | 11 | /** 12 | * Stops the server 13 | * 14 | * @author Creart 15 | */ 16 | public class StopCommand extends Command { 17 | 18 | /** 19 | * Constructor 20 | */ 21 | public StopCommand() 22 | { 23 | super("stop", "Shuts GameStack down."); 24 | } 25 | 26 | @Override 27 | public void execute(CommandSender sender, String[] args) 28 | { 29 | sender.sendMessage("The server is going to be shut down."); 30 | StackServer.getInstance().stop(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/conf/ConfigurationConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.conf; 8 | 9 | /** 10 | * @author Creart 11 | */ 12 | public final class ConfigurationConstants { 13 | 14 | public static final String BROKER_SYSTEM = "broker.system"; 15 | public static final String BROKER_HOST = "broker.host"; 16 | public static final String BROKER_PORT = "broker.port"; 17 | public static final String BROKER_USERNAME = "broker.username"; 18 | public static final String BROKER_PASSWORD = "broker.password"; 19 | public static final String BROKER_VIRTUAL_HOST = "broker.virtual_host"; 20 | 21 | public static final String DATABASE_SYSTEM = "database.system"; 22 | public static final String DATABASE_HOST = "database.host"; 23 | public static final String DATABASE_PORT = "database.port"; 24 | public static final String DATABASE_USERNAME = "database.username"; 25 | public static final String DATABASE_PASSWORD = "database.password"; 26 | public static final String DATABASE_DB = "database.db"; 27 | 28 | private ConfigurationConstants() 29 | { 30 | // no instance 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/listener/EnqueueListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.listener; 8 | 9 | import fr.creart.gamestack.common.player.MessageType; 10 | import fr.creart.gamestack.common.player.Queueable; 11 | import fr.creart.gamestack.common.protocol.PacketListener; 12 | import fr.creart.gamestack.common.protocol.packet.result.EnqueueData; 13 | import fr.creart.gamestack.server.StackServer; 14 | import fr.creart.gamestack.server.util.Queueables; 15 | 16 | /** 17 | * Handles the {@link fr.creart.gamestack.common.protocol.packet.EnqueuePacket} 18 | * 19 | * @author Creart 20 | */ 21 | public class EnqueueListener implements PacketListener { 22 | 23 | private StackServer instance; 24 | 25 | { 26 | instance = StackServer.getInstance(); 27 | } 28 | 29 | @Override 30 | public void handlePacket(int packetId, EnqueueData result) 31 | { 32 | Queueable queueable = Queueables.fromUUIDArray(result.getPlayerUUIDs(), result.getPriority()); 33 | 34 | if (instance.getQueuesManager().enqueueObject(queueable, result.getMap())) 35 | queueable.sendMessage("#enqueue-success", MessageType.CHAT_MESSAGE); 36 | else 37 | queueable.sendMessage("enqueue-fail", MessageType.CHAT_MESSAGE); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/listener/HostUpdateListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.listener; 8 | 9 | import fr.creart.gamestack.common.protocol.PacketListener; 10 | import fr.creart.gamestack.common.protocol.packet.result.HostUpdate; 11 | import fr.creart.gamestack.server.StackServer; 12 | 13 | /** 14 | * Listens for host updates 15 | * 16 | * @author Creart 17 | */ 18 | public class HostUpdateListener implements PacketListener { 19 | 20 | private StackServer server; 21 | 22 | { 23 | server = StackServer.getInstance(); 24 | } 25 | 26 | @Override 27 | public void handlePacket(int packetId, HostUpdate result) 28 | { 29 | server.updateServer(result); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/listener/MinecraftUpdateListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.listener; 8 | 9 | import fr.creart.gamestack.common.log.CommonLogger; 10 | import fr.creart.gamestack.common.protocol.PacketListener; 11 | import fr.creart.gamestack.common.protocol.packet.result.MinecraftServerUpdate; 12 | import fr.creart.gamestack.server.StackServer; 13 | import fr.creart.gamestack.server.server.HostServer; 14 | 15 | /** 16 | * Listens for Minecraft updates 17 | * 18 | * @author Creart 19 | */ 20 | public class MinecraftUpdateListener implements PacketListener { 21 | 22 | private StackServer server; 23 | 24 | { 25 | server = StackServer.getInstance(); 26 | } 27 | 28 | @Override 29 | public void handlePacket(int packetId, MinecraftServerUpdate result) 30 | { 31 | HostServer host = server.getServer(result.getAddress()); 32 | 33 | if (host == null) { 34 | CommonLogger.error("No host server for the address: " + result.getAddress() + ". Could not add Minecraft server."); 35 | return; 36 | } 37 | 38 | host.updateMinecraftServer(result.getPort(), result); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/listener/PlayerEnqueueListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.listener; 8 | 9 | import fr.creart.gamestack.common.protocol.PacketListener; 10 | import fr.creart.gamestack.common.protocol.packet.result.EnqueueData; 11 | import fr.creart.gamestack.server.StackServer; 12 | 13 | /** 14 | * @author Creart 15 | */ 16 | public class PlayerEnqueueListener implements PacketListener { 17 | 18 | private StackServer server; 19 | 20 | { 21 | server = StackServer.getInstance(); 22 | } 23 | 24 | @Override 25 | public void handlePacket(int packetId, EnqueueData result) 26 | { 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/listener/PullQueueListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.listener; 8 | 9 | import fr.creart.gamestack.common.protocol.PacketListener; 10 | import fr.creart.gamestack.common.protocol.packet.result.PullQueueData; 11 | import fr.creart.gamestack.server.StackServer; 12 | import fr.creart.gamestack.server.util.Queueables; 13 | 14 | /** 15 | * @author Creart 16 | */ 17 | public class PullQueueListener implements PacketListener { 18 | 19 | private StackServer server; 20 | 21 | { 22 | server = StackServer.getInstance(); 23 | } 24 | 25 | @Override 26 | public void handlePacket(int packetId, PullQueueData result) 27 | { 28 | server.getQueuesManager().dequeueObject( 29 | Queueables.fromUUIDArray(result.getPlayerUUIDs(), (byte) 0 /*we don't need the priority here, so we can just put a random value*/) 30 | ); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/logging/AuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package fr.creart.gamestack.server.logging; 2 | 3 | import com.google.common.base.Strings; 4 | import fr.creart.gamestack.common.log.CommonLogger; 5 | import fr.creart.gamestack.netty.protocol.SimplePacket; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelInboundHandlerAdapter; 8 | import java.util.UUID; 9 | 10 | /** 11 | * @author Creart 12 | */ 13 | public class AuthenticationHandler extends ChannelInboundHandlerAdapter { 14 | 15 | private String authToken; 16 | 17 | @Override 18 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception 19 | { 20 | SimplePacket packet = (SimplePacket) msg; 21 | if (Strings.isNullOrEmpty(authToken)) { 22 | if (packet.getId() != 0) 23 | ctx.close(); 24 | else { 25 | String gen = UUID.randomUUID().toString(); 26 | ctx.writeAndFlush(gen); 27 | authToken = gen; 28 | } 29 | } else { 30 | if (msg.equals(authToken)) { 31 | ctx.pipeline().addBefore("auth", "file", new LogFileHandler()); 32 | ctx.writeAndFlush("OK"); 33 | ctx.pipeline().remove(this); 34 | } else 35 | ctx.close(); 36 | } 37 | } 38 | 39 | @Override 40 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception 41 | { 42 | CommonLogger.error("An exception was encountered with Netty channel (Address: '" + ctx.channel().remoteAddress() + "').", cause); 43 | CommonLogger.error("Closing the channel."); 44 | ctx.close(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/logging/LogFileHandler.java: -------------------------------------------------------------------------------- 1 | package fr.creart.gamestack.server.logging; 2 | 3 | import com.google.common.base.Charsets; 4 | import fr.creart.gamestack.common.log.CommonLogger; 5 | import fr.creart.gamestack.netty.protocol.SimplePacket; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelInboundHandlerAdapter; 8 | import java.io.BufferedWriter; 9 | import java.nio.file.Files; 10 | import java.nio.file.Paths; 11 | 12 | /** 13 | * Rewrites the logs line per line 14 | * 15 | * @author Creart 16 | */ 17 | public class LogFileHandler extends ChannelInboundHandlerAdapter { 18 | 19 | private BufferedWriter output; 20 | 21 | @Override 22 | public void channelRead(ChannelHandlerContext ctx, Object o) throws Exception 23 | { 24 | SimplePacket packet = (SimplePacket) o; 25 | 26 | if (output == null) { 27 | output = Files.newBufferedWriter(Paths.get("logs/client/"), Charsets.UTF_8); 28 | // TODO: 20/12/2016 define the log file 29 | // should be => logs/client/host_server_name/mc_server_name.log 30 | // mc_server_name is actually the game + the number of games played of the game 31 | // but what is could be host_server_name? 32 | } 33 | 34 | if (packet.getId() == 3) { 35 | output.close(); 36 | CommonLogger.info("Done saving logs of '" + ctx.channel().remoteAddress() + "'."); 37 | ctx.close(); 38 | } else 39 | output.write(packet.getData()); 40 | } 41 | 42 | @Override 43 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception 44 | { 45 | CommonLogger.error( 46 | "An exception has been encountered during a file transfer with '" + ctx.channel().remoteAddress() + "'. Closing the channel", 47 | cause 48 | ); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/logging/LoggingServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.logging; 8 | 9 | import fr.creart.gamestack.common.log.CommonLogger; 10 | import fr.creart.gamestack.common.misc.Initialisable; 11 | import fr.creart.gamestack.netty.NettyUtil; 12 | import fr.creart.gamestack.netty.protocol.SimplePacketDecoder; 13 | import fr.creart.gamestack.netty.protocol.SimplePacketEncoder; 14 | import io.netty.bootstrap.ServerBootstrap; 15 | import io.netty.channel.Channel; 16 | import io.netty.channel.ChannelInitializer; 17 | import io.netty.channel.ChannelOption; 18 | import io.netty.channel.EventLoopGroup; 19 | import io.netty.channel.epoll.Epoll; 20 | import io.netty.channel.epoll.EpollServerSocketChannel; 21 | import io.netty.channel.socket.nio.NioServerSocketChannel; 22 | 23 | /** 24 | * Server which listens for logs from distant servers, usually sent before they are closed. 25 | * Centralises logs. 26 | * 27 | * @author Creart 28 | */ 29 | public class LoggingServer implements Initialisable, AutoCloseable { 30 | 31 | /* 32 | PROTOCOL 33 | ID 0 => AUTHENTICATION REQUEST 34 | ID 1 => AUTHENTICATION 35 | ID 2 => PART OF FILE 36 | ID 3 => EOF 37 | */ 38 | 39 | private ThreadGroup loggingGroup; 40 | private Channel channel; 41 | private EventLoopGroup boss; 42 | private EventLoopGroup worker; 43 | 44 | public LoggingServer(ThreadGroup parent) 45 | { 46 | loggingGroup = new ThreadGroup(parent, "Logging Server"); 47 | } 48 | 49 | @Override 50 | public void initialise() 51 | { 52 | try { 53 | boss = NettyUtil.createEventLoopGroup(3, loggingGroup); 54 | worker = NettyUtil.createEventLoopGroup(3, loggingGroup); 55 | ServerBootstrap s = new ServerBootstrap() 56 | .group(boss, worker) 57 | .childOption(ChannelOption.SO_KEEPALIVE, true) 58 | .childOption(ChannelOption.SO_BACKLOG, 100) 59 | .childOption(ChannelOption.SO_TIMEOUT, 10000) 60 | .channel(Epoll.isAvailable() ? EpollServerSocketChannel.class : NioServerSocketChannel.class) 61 | .childHandler(new ChannelInitializer() { 62 | @Override 63 | protected void initChannel(Channel channel) throws Exception 64 | { 65 | channel.pipeline().addLast( 66 | new SimplePacketDecoder(), 67 | new SimplePacketEncoder() 68 | ); 69 | channel.pipeline().addLast("auth", new AuthenticationHandler()); 70 | } 71 | }); 72 | channel = s.bind(28).sync().channel(); 73 | CommonLogger.info("The logging server is listening on port 28."); 74 | } catch (Exception e) { 75 | CommonLogger.fatal("Could not initialise Netty logging server!", e); 76 | } 77 | } 78 | 79 | @Override 80 | public void close() 81 | { 82 | try { 83 | if (!boss.isShutdown()) 84 | boss.shutdownGracefully(); 85 | if (!worker.isShutdown()) 86 | worker.shutdownGracefully(); 87 | 88 | if (channel.isOpen()) 89 | channel.close().sync(); 90 | } catch (Exception e) { 91 | CommonLogger.error("Could not correctly close logging server.", e); 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/queue/QueuesManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.queue; 8 | 9 | import fr.creart.gamestack.common.game.GameMap; 10 | import fr.creart.gamestack.common.pipeline.Pipeline; 11 | import fr.creart.gamestack.common.pipeline.SimplePipeline; 12 | import fr.creart.gamestack.common.player.Queueable; 13 | import fr.creart.gamestack.server.StackServer; 14 | import fr.creart.gamestack.server.server.HostServer; 15 | import java.util.Collection; 16 | import java.util.HashMap; 17 | import java.util.HashSet; 18 | import java.util.Map; 19 | import java.util.Set; 20 | import java.util.concurrent.locks.ReadWriteLock; 21 | import java.util.concurrent.locks.ReentrantReadWriteLock; 22 | import org.apache.commons.lang3.Validate; 23 | 24 | /** 25 | * Manages the player queues. (The queues where players are waiting to play.) 26 | * 27 | * @author Creart 28 | */ 29 | public class QueuesManager { 30 | 31 | private ReadWriteLock lock = new ReentrantReadWriteLock(); 32 | private Map queues = new HashMap<>(); 33 | private Pipeline> requestPipeline = new SimplePipeline<>(); 34 | 35 | public void lookup() 36 | { 37 | Set filled = new HashSet<>(); 38 | requestPipeline.call(filled); 39 | 40 | if (filled.isEmpty()) 41 | return; 42 | 43 | for (PlayerQueue q : filled) { 44 | HostServer server = StackServer.getInstance().getBestServer(); 45 | // TODO: 19/12/2016 create settings for minimal player amount 46 | if (server == null || !server.canHost(q.getGameMap(), (short) 0)) { 47 | // cannot satisfy demand, we need new servers 48 | } 49 | else { 50 | // now, we can send players 51 | // q.getToSend, etc. 52 | } 53 | } 54 | } 55 | 56 | public void createQueues() 57 | { 58 | 59 | } 60 | 61 | /** 62 | * Returns true if the {@link Queueable} has been successfully added to the requested queue 63 | * 64 | * @param queueable the queuable object in itself 65 | * @param map the requested queue (the map associated to it) 66 | * @return true if the {@link Queueable} has been successfully added to the requested queue 67 | */ 68 | public boolean enqueueObject(Queueable queueable, GameMap map) 69 | { 70 | Validate.notNull(queueable, "queueable can't be null"); 71 | 72 | PlayerQueue queue = null; 73 | 74 | lock.readLock().lock(); 75 | try { 76 | queue = queues.get(map); 77 | } finally { 78 | lock.readLock().unlock(); 79 | } 80 | 81 | if (queue != null) { 82 | queue.addQueueable(queueable); 83 | return true; 84 | } 85 | 86 | return false; 87 | } 88 | 89 | /** 90 | * Returns true if the given object has been removed from a queue 91 | * 92 | * @param queueable the queueable object to remove 93 | * @return true if the given object has been removed from a queue 94 | */ 95 | public boolean dequeueObject(Queueable queueable) 96 | { 97 | Validate.notNull(queueable, "queueable item can't be null"); 98 | 99 | lock.readLock().lock(); 100 | try { 101 | for (PlayerQueue queue : queues.values()) 102 | if (queue.removeQueueable(queueable)) 103 | return true; 104 | return false; 105 | } finally { 106 | lock.readLock().unlock(); 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /server/src/main/java/fr/creart/gamestack/server/util/Queueables.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | package fr.creart.gamestack.server.util; 8 | 9 | import fr.creart.gamestack.common.player.Party; 10 | import fr.creart.gamestack.common.player.Player; 11 | import fr.creart.gamestack.common.player.Queueable; 12 | import java.util.Arrays; 13 | import java.util.stream.Collectors; 14 | import org.apache.commons.lang3.Validate; 15 | 16 | /** 17 | * Util class for {@link Queueable} objects 18 | * 19 | * @author Creart 20 | */ 21 | public final class Queueables { 22 | 23 | private Queueables() 24 | { 25 | // no instance 26 | } 27 | 28 | /** 29 | * Returns a {@link Queueable} object from the uuid array of a packet 30 | * 31 | * @param uuids the UUIDs 32 | * @param priority priority 33 | * @return a {@link Queueable} object from the uuid array of a packet 34 | */ 35 | public static Queueable fromUUIDArray(String[] uuids, byte priority) 36 | { 37 | Validate.notEmpty(uuids, "uuids can't be empty"); 38 | 39 | return uuids.length == 1 ? 40 | new Player(uuids[0], priority) : 41 | new Party(new Player(uuids[0], priority), 42 | Arrays.stream(Arrays.copyOfRange(uuids, 1, uuids.length - 1)) 43 | .map(uuid -> new Player(uuid, (byte) 0)).collect(Collectors.toList()).toArray(new Player[0])); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /server/src/main/resources/gamestack.properties: -------------------------------------------------------------------------------- 1 | # GameStack and GSS (GameStack Server) configuration 2 | slots=100 3 | gameweight-resizer=false -------------------------------------------------------------------------------- /server/src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /server/src/main/resources/messages.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olsdavis/GameStack/84446848a121185e9343373474e7bad7376da083/server/src/main/resources/messages.properties -------------------------------------------------------------------------------- /server/src/main/resources/requests.properties: -------------------------------------------------------------------------------- 1 | create_games_table="CREATE TABLE {0}games \ 2 | ( \ 3 | id SERIAL PRIMARY KEY, \ 4 | name CHARACTER VARYING(30) NOT NULL, \ 5 | required_files TEXT[] \ 6 | ); \ 7 | CREATE UNIQUE INDEX games_id_uindex ON {0}games (id); \ 8 | CREATE UNIQUE INDEX games_name_uindex ON {0}games (name);" 9 | # Arg {0} is replaced by "public." if the database if postgresql, otherwise it is replcaed by an empty String 10 | create_game_maps_table="" --------------------------------------------------------------------------------