{"id":15164402,"url":"https://github.com/congcoi123/tenio","last_synced_at":"2025-04-05T13:08:46.361Z","repository":{"id":39906440,"uuid":"226617617","full_name":"congcoi123/tenio","owner":"congcoi123","description":"TenIO is an open-source project for making online games that includes a java NIO (Non-blocking I/O) based server specifically designed for multiplayer games and simple existing game clients for rapid development: Libgdx (Java), Cocos2d-x (C++), Unity (C#), Phaserjs (Javascript).","archived":false,"fork":false,"pushed_at":"2025-01-15T19:58:38.000Z","size":33611,"stargazers_count":119,"open_issues_count":8,"forks_count":12,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-29T12:09:20.160Z","etag":null,"topics":["architecture","cocos2d-x","framework","game-server","gameserver","java","java-17","java-nio","jetty","kcp","kcp-java","libgdx","microservices","mmo","mmorpg","multiplayer","netty","phaserjs","unity"],"latest_commit_sha":null,"homepage":"https://congcoi123.dev","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/congcoi123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"patreon":"congcoi123","custom":["https://www.buymeacoffee.com/congcoi123"]}},"created_at":"2019-12-08T05:07:00.000Z","updated_at":"2025-03-06T07:59:12.000Z","dependencies_parsed_at":"2023-01-31T00:46:10.395Z","dependency_job_id":"bc0494e8-ddb2-4cd1-89fb-9983865068fe","html_url":"https://github.com/congcoi123/tenio","commit_stats":{"total_commits":529,"total_committers":5,"mean_commits":105.8,"dds":0.052930056710775,"last_synced_commit":"2de408b09bce3e23022f6c11afed7986f9e06f68"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/congcoi123","download_url":"https://codeload.github.com/congcoi123/tenio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339158,"owners_count":20923014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["architecture","cocos2d-x","framework","game-server","gameserver","java","java-17","java-nio","jetty","kcp","kcp-java","libgdx","microservices","mmo","mmorpg","multiplayer","netty","phaserjs","unity"],"created_at":"2024-09-27T03:21:47.075Z","updated_at":"2025-04-05T13:08:46.346Z","avatar_url":"https://github.com/congcoi123.png","language":"Java","funding_links":["https://patreon.com/congcoi123","https://www.buymeacoffee.com/congcoi123"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"#\"\u003e\n        \u003cimg src=\"assets/tenio-github-logo.png\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"#\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/last-commit/congcoi123/tenio\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/congcoi123/tenio/issues\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/issues/congcoi123/tenio\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"CONTRIBUTING.md\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://discord.gg/ybkNU87Psy\"\u003e\n        \u003cimg src=\"https://img.shields.io/discord/1146091189456613407?logo=discord\u0026logoColor=white\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\n# TenIO [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=TenIO%20is%20a%20java%20NIO%20based%20server%20specifically%20designed%20for%20multiplayer%20games.%0D%0A\u0026url=https://github.com/congcoi123/tenio%0D%0A\u0026hashtags=tenio,java,gameserver,multiplayer,nio,netty,jetty,msgpack,cocos2dx,unity,libgdx,phaserjs%0D%0A\u0026via=congcoi123)\n`TenIO` is an open-source project to create multiplayer online games that includes a java NIO (Non-blocking I/O) based server specifically designed for multiplayer games, which supports UDP, TCP, Websocket, HTTP transports, and available simple client projects for quick development.\n\n## Features\n- Scalable, distributed design\n- Easy-to-use, OOP design\n- Based on standard Java development, ensuring cross-platform support\n- Simple event handlers implementation\n- Simple physic simulator and debugger\n- Have simple existing game clients for rapid development\n\n## Showcases\n| [\u003cimg src=\"assets/game-box-online-logo.png\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eGame Box Online\u003c/b\u003e\u003c/sub\u003e](https://www.youtube.com/watch?v=yLo2TRYd7Yw)\u003cbr /\u003e        | [\u003cimg src=\"assets/gold-miner-online-logo.png\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eGold Miner Online\u003c/b\u003e\u003c/sub\u003e](https://www.youtube.com/watch?v=BBv5IQFHLjc)\u003cbr /\u003e        | [\u003cimg src=\"assets/retro-brick-online-logo.png\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBrick Game Online\u003c/b\u003e\u003c/sub\u003e](https://www.youtube.com/watch?v=nojkJMAfG6Y)\u003cbr /\u003e |\n| :-----------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n\n## First Glimpse\nSimple Movement Simulation  \n![Simple Movement Simulation](assets/movement-simulation-example-4.gif)\n\n## Simple Implementation\n- Establishes a simple server with only a single Java class\n\n```Java\n/**\n * This class shows how a simple server handle messages that came from a client.\n */\n@Bootstrap\npublic final class TestSimpleServer {\n\n  public static void main(String[] params) {\n    ApplicationLauncher.run(TestSimpleServer.class, params);\n  }\n\n  /**\n   * Create your own configurations.\n   */\n  @Setting\n  public static class TestConfiguration extends CoreConfiguration implements Configuration {\n\n    @Override\n    protected void extend(Map\u003cString, String\u003e extProperties) {\n      for (Map.Entry\u003cString, String\u003e entry : extProperties.entrySet()) {\n        var paramName = entry.getKey();\n        push(ExampleConfigurationType.getByValue(paramName), String.valueOf(entry.getValue()));\n      }\n    }\n  }\n\n  /**\n   * Define your handlers.\n   */\n\n  @EventHandler\n  public static class ConnectionEstablishedHandler extends AbstractHandler\n      implements EventConnectionEstablishedResult {\n\n    @Override\n    public void handle(Session session, DataCollection message,\n                       ConnectionEstablishedResult result) {\n      if (result == ConnectionEstablishedResult.SUCCESS) {\n        var request = (ZeroMap) message;\n\n        api().login(request.getString(SharedEventKey.KEY_PLAYER_LOGIN), session);\n      }\n    }\n  }\n\n  @EventHandler\n  public static class PlayerLoggedInHandler extends AbstractHandler\n      implements EventPlayerLoggedinResult\u003cPlayer\u003e {\n\n    @Override\n    public void handle(Player player, PlayerLoggedInResult result) {\n      if (result == PlayerLoggedInResult.SUCCESS) {\n        var parcel = map().putString(SharedEventKey.KEY_PLAYER_LOGIN,\n            String.format(\"Welcome to server: %s\", player.getName()));\n\n        response().setContent(parcel.toBinary()).setRecipientPlayer(player).write();\n      }\n    }\n  }\n\n  @EventHandler\n  public static class ReceivedMessageFromPlayerHandler extends AbstractHandler\n      implements EventReceivedMessageFromPlayer\u003cPlayer\u003e {\n\n    @Override\n    public void handle(Player player, DataCollection message) {\n      var parcel =\n          map().putString(SharedEventKey.KEY_CLIENT_SERVER_ECHO, String.format(\"Echo(%s): %s\",\n              player.getName(),\n              ((ZeroMap) message).getString(SharedEventKey.KEY_CLIENT_SERVER_ECHO)));\n\n      response().setContent(parcel.toBinary()).setRecipientPlayer(player).write();\n    }\n  }\n}\n```\n\n- Supports self-defined commands to interact with the server conveniently\n1) Usage\n  \n```text\n2022-11-20 05:20:38,256 [main] INFO  com.tenio.core.server.ServerImpl - [SERVER][Example] Started\n$ help\nhelp - Shows all supporting commands\n  [\u003ccommand\u003e,\u003ccommand\u003e,\u003ccommand\u003e]\ninfo - Provides brief information about players and rooms on the server\n  player\n  room\nplayer - Logout the first player from the server\n  logout first\nserver - Allows stopping or restarting the server\n  stop\n  restart\nunban - Allows removing banned Ip addresses from the ban list\n  [\u003caddress\u003e,\u003ccommand\u003e,\u003ccommand\u003e]\n$ info player\n\u003e There are 1 players \u003e The first 10 entities \u003e [Player{name='IkjvI', properties={}, session=Session{id=0, name='IkjvI', transportType=TCP, createdTime=1668918078524, lastReadTime=1668918078524, lastWriteTime=1668918078524, lastActivityTime=1668918078524, readBytes=75, writtenBytes=120, droppedPackets=0, inactivatedTime=0, datagramRemoteSocketAddress=null, clientAddress='127.0.0.1', clientPort=60659, serverPort=8032, serverAddress='127.0.0.1', maxIdleTimeInSecond=0, activated=true, connected=true, hasUdp=false, enabledKcp=false, hasKcp=false}, currentRoom=null, state=null, roleInRoom=SPECTATOR, lastLoginTime=1668918078589, lastJoinedRoomTime=1668918078588, playerSlotInCurrentRoom=-1, loggedIn=true, activated=true, hasSession=true}]\n$ \n```\n\n2) Make sure to set the command usage flag in _**setting.json**_ file to be **enabled**\n\n```JSON\n{\n  \"command\": {\n    \"enabled\": true\n  },\n  \"plugin\": {\n    \"enabled\": false,\n    \"path\": \"/plugin\"\n  }\n}\n``` \n\n3) Simple implementation\n```Java\n@Command(label = \"player\", usage = {\n    \"logout first\"\n}, description = \"Logout the first player from the server\")\npublic class PlayerCommand extends AbstractCommandHandler {\n\n  @Override\n  public void execute(List\u003cString\u003e args) {\n    var action = args.get(0);\n    var param = args.get(1);\n\n    if (action.equals(\"logout\") \u0026\u0026 param.equals(\"first\")) {\n      var players = api().getReadonlyPlayersList();\n      if (players.isEmpty()) {\n        CommandUtility.INSTANCE.showConsoleMessage(\"Empty list of players.\");\n        return;\n      }\n      var firstPlayer = players.get(0);\n      CommandUtility.INSTANCE.showConsoleMessage(\"Player {\" + firstPlayer.getName() + \"} is \" +\n          \"going to logout.\");\n      api().logout(firstPlayer);\n    } else {\n      CommandUtility.INSTANCE.showConsoleMessage(\"Invalid action.\");\n    }\n  }\n}\n``` \n\n## Wiki\nThe [wiki](https://github.com/congcoi123/tenio/wiki) provides implementation level details and answers to general questions that a developer starting to use `TenIO` might have about it.\n\n## Clients\n| [\u003cimg src=\"assets/cocos2dx-logo.png\" width=\"150px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTenIO Cocos2dx\u003c/b\u003e\u003c/sub\u003e](https://github.com/congcoi123/tenio-cocos2dx)\u003cbr /\u003e        | [\u003cimg src=\"assets/libgdx-logo.png\" width=\"150px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTenIO Libgdx\u003c/b\u003e\u003c/sub\u003e](https://github.com/congcoi123/tenio-libgdx)\u003cbr /\u003e | [\u003cimg src=\"assets/unity-logo.png\" width=\"150px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTenIO Unity\u003c/b\u003e\u003c/sub\u003e](https://github.com/congcoi123/tenio-unity)\u003cbr /\u003e          | [\u003cimg src=\"assets/phaserjs-logo.png\" width=\"150px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTenIO Phaserjs\u003c/b\u003e\u003c/sub\u003e](https://github.com/congcoi123/tenio-phaserjs)\u003cbr /\u003e |\n| :-----------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n\n## Framework\nThe project is strongly based on the same name framework as you can be referenced by the following repositories.\n- [`tenio-common`](https://github.com/congcoi123/tenio-common.git)\n- [`tenio-core`](https://github.com/congcoi123/tenio-core.git)\n- [`tenio-engine`](https://github.com/congcoi123/tenio-engine.git)\n\n## Requirements\n```txt\n- Java 17\n```\n\n## License\nThe `TenIO` project is currently available under the [MIT](LICENSE) License.\n\n## Contributing\nPlease check out the [contributing guideline](CONTRIBUTING.md) for more details.\n\n## Documentations\nPlease check out the [documentations directory](documentations) for more details.\n\n## Installation\n```sh\n$ git clone https://github.com/congcoi123/tenio.git\n```\n\n## Examples\n### Collection\nPlease check out [`this repository`](https://github.com/congcoi123/tenio-examples.git) for references.\n### Wanna try Kotlin?\nThen you should check out [`this showcase`](https://github.com/congcoi123/lonely-dragon.git) for more details.\n\n\u003e Happy coding !\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcongcoi123%2Ftenio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcongcoi123%2Ftenio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcongcoi123%2Ftenio/lists"}