{"id":15524076,"url":"https://github.com/congcoi123/tenio-examples","last_synced_at":"2025-04-23T07:23:36.134Z","repository":{"id":41966687,"uuid":"417116142","full_name":"congcoi123/tenio-examples","owner":"congcoi123","description":"A collection of examples is for the TenIO framework.","archived":false,"fork":false,"pushed_at":"2025-01-15T19:55:12.000Z","size":468,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T22:41:17.447Z","etag":null,"topics":["examples","game-development","gameserver","java","java17","kcp","kcp-java","tenio"],"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":"CHANGELOG.md","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":"2021-10-14T12:11:12.000Z","updated_at":"2025-01-15T19:55:14.000Z","dependencies_parsed_at":"2025-03-05T09:35:05.516Z","dependency_job_id":"a67652d6-c5ff-43ea-8b8a-fd37dcb41634","html_url":"https://github.com/congcoi123/tenio-examples","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio-examples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio-examples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio-examples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/congcoi123%2Ftenio-examples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/congcoi123","download_url":"https://codeload.github.com/congcoi123/tenio-examples/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250388225,"owners_count":21422290,"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":["examples","game-development","gameserver","java","java17","kcp","kcp-java","tenio"],"created_at":"2024-10-02T10:49:07.261Z","updated_at":"2025-04-23T07:23:36.108Z","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=\"https://github.com/congcoi123/tenio/blob/master/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-examples\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/congcoi123/tenio-examples/issues\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/issues/congcoi123/tenio-examples\"\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# TenIO Examples Project [![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`](https://github.com/congcoi123/tenio) is an open-source project to create multiplayer online games that includes a java NIO (Non-blocking I/O) \nbased server specifically designed for multiplayer games, which supports UDP, TCP, Websocket, HTTP transports, and available simple client projects for quick development.\n\nThis project contains a collection of examples that show you how to manipulate the framework.\n\n## Dependencies\n```txt\n- tenio-core 0.6.0\n- tenio-engine 0.6.0\n```\n\n## Requirements\n- Java 17\n\n## License\nThe [`TenIO`](https://github.com/congcoi123/tenio) project is currently available under the [MIT](LICENSE) License.\n\n## Changelog\nPlease check out the [changelog](CHANGELOG.md) for more details.\n\n## Contributing\nPlease check out the [contributing guideline](CONTRIBUTING.md) for more details.\n\n## Installation\n```sh\n$ git clone https://github.com/congcoi123/tenio-examples.git\n```\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\t[\u003ccommand\u003e,\u003ccommand\u003e,\u003ccommand\u003e]\ninfo - Provides brief information about players and rooms on the server\n\tplayer\n\troom\nplayer - Logout the first player from the server\n\tlogout first\nserver - Allows stopping or restarting the server\n\tstop\n\trestart\nunban - Allows removing banned Ip addresses from the ban list\n\t[\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\t\"command\": {\n\t\t\"enabled\": true\n\t},\n\t\"plugin\": {\n\t\t\"enabled\": false,\n\t\t\"path\": \"/plugin\"\n\t}\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## Examples\nPlease start the server before its corresponding client in each example package.\n```code\n$ java \u003cserver_main_class\u003e \u003cserver_configuration_file.xml\u003e\n```\nFor instance:\n```code\n$ java TestServerLogin configuration.example1.xml\n```\n\n```txt\n|-- example\n    |-- example0\n    |   |-- TestSimpleClient\n    |   |-- TestSimpleServer\n    |-- example1\n    |   |-- TestClientLogin\n    |   |-- TestServerLogin\n    |-- example2\n    |   |-- (*)TestFsmMechanism\n    |-- example3\n    |   |-- TestClientAccessDatagramChannel\n    |   |-- TestServerAccessDatagramChannel\n    |-- example4\n    |   |-- TestClientMovement\n    |   |-- TestServerMovement\n    |   |-- (*)TestMovementMechanism\n    |-- example5\n    |   |-- (*)TestEcsMechanism\n    |-- example6\n    |   |-- TestClientEchoStress\n    |   |-- TestServerEchoStress\n    |-- example7\n    |   |-- TestServerWebsocket\n    |-- example8\n    |   |-- TestClientRestful\n    |   |-- TestServerRestful\n    |-- example9\n    |   |-- TestClientKcpEcho\n    |   |-- TestServerKcpEcho\n    |-- example10\n    |   |-- TestClientMsgPackEcho\n    |   |-- TestServerMsgPackEcho\n    |-- example11\n    |   |-- TestClientCommand\n    |   |-- TestServerCommand\n```\n\n\u003e Happy coding !\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcongcoi123%2Ftenio-examples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcongcoi123%2Ftenio-examples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcongcoi123%2Ftenio-examples/lists"}