├── .classpath
├── .gitignore
├── .project
├── GetStarted.md
├── LICENSE
├── Plugin.md
├── README.md
├── README_zh.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── rukkit.png
├── settings.gradle
├── src
└── main
│ ├── java
│ └── cn
│ │ └── rukkit
│ │ ├── Launsjsnsnsn.java
│ │ ├── Rukkit.java
│ │ ├── RukkitLauncher.java
│ │ ├── RukkitSaveReader.java
│ │ ├── command
│ │ ├── ChatCommand.java
│ │ ├── ChatCommandListener.java
│ │ ├── Command.java
│ │ ├── CommandHandler.java
│ │ ├── CommandManager.java
│ │ ├── ServerCommand.java
│ │ ├── ServerCommandCompleter.java
│ │ ├── ServerCommandListener.java
│ │ └── completer
│ │ │ └── PlayerCompleter.java
│ │ ├── config
│ │ ├── BaseConfig.java
│ │ ├── RoundConfig.java
│ │ └── RukkitConfig.java
│ │ ├── event
│ │ ├── Cancellable.java
│ │ ├── Event.java
│ │ ├── EventHandler.java
│ │ ├── EventListener.java
│ │ ├── EventListenerContainer.java
│ │ ├── ListenerList.java
│ │ ├── action
│ │ │ ├── ActionEvent.java
│ │ │ ├── BuildEvent.java
│ │ │ ├── MoveEvent.java
│ │ │ ├── PingEvent.java
│ │ │ ├── RallyEvent.java
│ │ │ └── TaskEvent.java
│ │ ├── player
│ │ │ ├── OnPlayerPreRegisterEvent.java
│ │ │ ├── PlayerChatEvent.java
│ │ │ ├── PlayerEvent.java
│ │ │ ├── PlayerJoinEvent.java
│ │ │ ├── PlayerLeftEvent.java
│ │ │ └── PlayerReconnectEvent.java
│ │ ├── room
│ │ │ ├── RoomStartGameEvent.java
│ │ │ └── RoomStopGameEvent.java
│ │ └── server
│ │ │ ├── ServerEvent.java
│ │ │ └── ServerQuestionRespondEvent.java
│ │ ├── game
│ │ ├── CheckSumList.java
│ │ ├── GameActions.java
│ │ ├── GlobalPlayerManager.java
│ │ ├── NetworkPlayer.java
│ │ ├── NetworkPlayerData.java
│ │ ├── PingType.java
│ │ ├── PlayerManager.java
│ │ ├── SaveData.java
│ │ ├── SaveManager.java
│ │ ├── UnitType.java
│ │ ├── map
│ │ │ ├── CustomMapLoader.java
│ │ │ └── OfficialMap.java
│ │ ├── mod
│ │ │ ├── Mod.java
│ │ │ ├── ModLoader.java
│ │ │ └── ModManager.java
│ │ └── unit
│ │ │ └── InternalUnit.java
│ │ ├── network
│ │ ├── Connection.java.bak
│ │ ├── ConnectionHandler.java
│ │ ├── GameInputStream.java
│ │ ├── GameOutputStream.java
│ │ ├── GameServer.java.bak
│ │ ├── GlobalConnectionManager.java
│ │ ├── GzipDecoder.java
│ │ ├── GzipEncoder.java
│ │ ├── NetworkRoom.java
│ │ ├── RoomConnection.java
│ │ ├── RoomConnectionManager.java
│ │ ├── RoomGameServer.java
│ │ ├── RoomManager.java
│ │ ├── command
│ │ │ └── GameCommand.java
│ │ └── packet
│ │ │ ├── Packet.java
│ │ │ ├── PacketDecoder.java
│ │ │ └── PacketEncoder.java
│ │ ├── plugin
│ │ ├── Plugin.java
│ │ ├── PluginConfig.java
│ │ ├── PluginManager.java
│ │ ├── RukkitPlugin.java
│ │ └── internal
│ │ │ ├── BasePlugin.java
│ │ │ ├── CommandPlugin.java
│ │ │ ├── InternalRukkitPlugin.java
│ │ │ ├── NoStopCommandPlugin.java
│ │ │ ├── ScriptPlugin.java
│ │ │ ├── ServerCommandPlugin.java
│ │ │ ├── TestPlugin.java
│ │ │ └── TestPluginConfig.java
│ │ ├── service
│ │ ├── Service.java
│ │ ├── ServiceManager.java
│ │ ├── TerminalService.java
│ │ └── ThreadManager.java
│ │ └── util
│ │ ├── GameUtils.java
│ │ ├── LangUtil.java
│ │ ├── MathUtil.java
│ │ ├── VerifyUtil.java
│ │ └── Vote.java
│ └── resources
│ ├── defaultSave
│ ├── i18n
│ ├── messages.properties
│ ├── messages_en_US.properties
│ ├── messages_ru.properties
│ └── messages_zh_CN.properties
│ ├── logback.xml
│ ├── mod_default.1.14.json
│ └── mod_default.json
├── start.bat
└── start.sh
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.aar
4 | *.ap_
5 | *.aab
6 |
7 | # Files for the ART/Dalvik VM
8 | *.dex
9 |
10 | # Java class files
11 | *.class
12 |
13 | # Generated files
14 | bin/
15 | gen/
16 | out/
17 | # Uncomment the following line in case you need and you don't have the release build type files in your app
18 | # release/
19 |
20 | # Gradle files
21 | .gradle/
22 | build/
23 |
24 | # Local configuration file (sdk path, etc)
25 | local.properties
26 |
27 | #VsCode file
28 | .vscode/
29 |
30 | # Proguard folder generated by Eclipse
31 | proguard/
32 |
33 | # Log Files
34 | *.log
35 |
36 | # Android Studio Navigation editor temp files
37 | .navigation/
38 |
39 | # Android Studio captures folder
40 | captures/
41 |
42 | # IntelliJ
43 | *.iml
44 | .idea/workspace.xml
45 | .idea/tasks.xml
46 | .idea/gradle.xml
47 | .idea/assetWizardSettings.xml
48 | .idea/dictionaries
49 | .idea/libraries
50 | # Android Studio 3 in .gitignore file.
51 | .idea/caches
52 | .idea/modules.xml
53 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you
54 | .idea/navEditor.xml
55 |
56 | # Keystore files
57 | # Uncomment the following lines if you do not want to check your keystore files in.
58 | #*.jks
59 | #*.keystore
60 |
61 | # External native build folder generated in Android Studio 2.2 and later
62 | .externalNativeBuild
63 | .cxx/
64 |
65 | # Google Services (e.g. APIs or Firebase)
66 | # google-services.json
67 |
68 | # Freeline
69 | freeline.py
70 | freeline/
71 | freeline_project_description.json
72 |
73 | # fastlane
74 | fastlane/report.xml
75 | fastlane/Preview.html
76 | fastlane/screenshots
77 | fastlane/test_output
78 | fastlane/readme.md
79 |
80 | # Version control
81 | vcs.xml
82 |
83 | # lint
84 | lint/intermediates/
85 | lint/generated/
86 | lint/outputs/
87 | lint/tmp/
88 | # lint/reports/
89 |
90 | # Rukkit generated dir
91 | maps/
92 | mods/
93 | plugins/
94 |
95 | rukkit.yml
96 | round.yml
97 | server.properties
98 | .idea
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | Rukkit
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/GetStarted.md:
--------------------------------------------------------------------------------
1 | ## How to compile rukkit?
2 | Rukkit now support gradle.Just using gradle to compile this project.
3 |
4 | For example:
5 | 1. clone this project.
6 | ```shell
7 | git clone https://github.com/RukkitDev/Rukkit
8 | ```
9 | 2. using gradle to run a Rukkit server:
10 | ```shell
11 | gradle run
12 | ```
13 | 3. or compile the project.
14 | ```shell
15 | gradle buildRukkit
16 | ```
17 | 4. check the dir build/outputs and run start.sh/start.bat,and enjoy your server!
--------------------------------------------------------------------------------
/Plugin.md:
--------------------------------------------------------------------------------
1 | # Plugin indroduction
2 | ## Getting started
3 | to start a plugin project, you need to import the whole dependences in libs,including current rukkit release.
4 | ## First Plugin
5 | to start with this framework:
6 |
7 | - src
8 | - MyPlugin.java
9 | - plugin.yml
10 |
11 | ### plugin.yml
12 | ```yaml
13 | author: author-name
14 | version: 1.0.0
15 | name: my-plugin
16 | #Plugin API version to support.
17 | apiVersion: 0.5.x
18 | #Main Plugin Class to load.
19 | pluginClass: MyPlugin
20 | ```
21 |
22 | ### MyPlugin.java
23 | ```java
24 | public class MyPlugin extends RukkitPlugin {
25 | //Executes when PluginManager init
26 | @Override
27 | public void onStart() {
28 | //Do something...
29 | }
30 | //Executes when Server Started.
31 | @Override
32 | public void onDone() {
33 | //Do something...
34 | }
35 | //Executes when Server stopped.
36 | @Override
37 | public void onStop() {
38 | //Do something...
39 | }
40 | }
41 | ```
42 |
43 | Packed them to jar, drop jar into server/plugins folder.You might see this:
44 | ```txt
45 | PluginManager::Loading my-plugin(v1.0.0)...
46 | ```
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [中文](README_zh.md)
2 |
3 | # Rukkit Project
4 | 
5 | []({linkUrl})
6 | [](https://discord.gg/JJJ6GST)
7 | ## What is Rukkit?
8 | Rukkit is a Rustedwarfare Server,you can use it to run a private server on your vps or other devices.
9 | It's more like Dedicated server but more features like custom maps or mods, extra plugins.
10 | This project based on netty framework so it as stable as Dedicated Servers.
11 |
12 | ## Progress
13 | - [x] Basic Game Play
14 | - [x] Custom maps
15 | - [x] Game sync & rejoin (support offical maps and custom too)
16 | - [x] Basic Plugin System
17 | - [x] Mod server by mod's metadata (need a exportTool)
18 | - [x] 10p+ Multiplayer supported (only 1.14+)
19 | - [ ] No-stop game future.
20 | - [ ] Game hook(Events) supported some event not all.
21 | - [ ] Anti-Cheat sync (need a game Simulation layer)
22 | - [ ] Advanced gameCommand & save modification. (it's hard to make changes to them,the most result is crash the game.)
23 | - [ ] Relay mode (maybe in future version)
24 |
25 | ## About
26 | Some plugin system design referenced [Nukkit](https://github.com/Nukkit/Nukkit).
27 |
28 | ## Unstable warning
29 | this is still a unstable build.If you find bugs,please commit issues.
30 | if you fixed some bugs, you can have a PR.
31 |
--------------------------------------------------------------------------------
/README_zh.md:
--------------------------------------------------------------------------------
1 | # Rukkit 项目
2 | 
3 | [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ekpIy0vjVhGpCZ5cpszxP6vaR9nRIaFc&authKey=wtgSzxj7uZ7zk%2F4GO20B%2FWVXP9WcZMC7c2FMynjZkx8B%2BkntiSeybBZZ6O3g7p90&noverify=0&group_code=751977820)
4 | [](https://discord.gg/JJJ6GST)
5 | ## 什么是 Rukkit?
6 | Rukkit是一个第三方铁锈战争服务器,你可以使用它来构建铁锈托管服务器,拥有类官服体验,性能更好,功能更强,支持自定义mod/地图和服务器插件,拥有游戏监听机制,允许你在游戏时拓展你的游戏体验,或是在游戏中创造新的玩法。Rukkit基于netty高性能框架,理论性能比官房/客户端更强。
7 |
8 | ## 目前进度
9 | - [x] 基础游戏(能玩)
10 | - [x] 自定义地图
11 | - [x] 游戏同步/玩家重进(只支持官方地图)
12 | - [x] 服务端插件系统
13 | - [x] 基于元信息的mod系统(需要拿工具转换rwmod)
14 | - [x] 10人以上玩家支持 (1.14+)
15 | - [ ] 不停止模式(支持随进随出,投票换图)
16 | - [ ] 游戏事件机制(支持一些)
17 | - [ ] 反作弊检查(需要游戏模拟层,做不出)
18 | - [ ] 游戏指令重构建. (比较困难,而且容易炸游戏.)
19 | - [ ] 中继模式 (咕咕咕)
20 |
21 | ## 关于
22 | 插件系统设计借鉴[Nukkit](https://github.com/Nukkit/Nukkit)
23 |
24 | ## 不稳定警告
25 | 这个版本仍然不稳定。如果你发现的bug 请提出issue,或者PR,感谢你的支持!
26 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This build file was generated by the Gradle 'init' task.
3 | *
4 | * This generated file contains a commented-out sample Java project to get you started.
5 | * For more details take a look at the Java Quickstart chapter in the Gradle
6 | * user guide available at https://docs.gradle.org/4.4.1/userguide/tutorial_java_projects.html
7 | */
8 |
9 | // Apply the java plugin to add support for Java
10 | plugins {
11 | id 'java'
12 | id 'application'
13 | id 'com.github.johnrengelman.shadow' version '7.0.0'
14 | }
15 |
16 | [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF8'
17 | final def RUKKIT_VERSION = "0.9.4-dev"
18 | mainClassName = 'cn.rukkit.RukkitLauncher'
19 |
20 | // In this section you declare where to find the dependencies of your project
21 | repositories {
22 | // Use 'jcenter' for resolving your dependencies.
23 | // You can declare any Maven/Ivy/file repository here.
24 | mavenCentral()
25 | }
26 |
27 | // In this section you declare the dependencies for your production and test code
28 | dependencies {
29 | // The production code uses the SLF4J logging API at compile time
30 | // compile 'org.slf4j:slf4j-api:1.7.25'
31 | implementation 'com.alibaba.fastjson2:fastjson2:2.0.41'
32 | implementation 'org.jline:jline-terminal:3.25.0'
33 | implementation 'org.jline:jline-console:3.25.0'
34 | implementation 'org.jline:jline:3.25.0'
35 | implementation 'org.jline:jline-reader:3.25.0'
36 | implementation 'org.jline:jline-terminal-jna:3.25.0'
37 | // https://mvnrepository.com/artifact/io.netty/netty-all
38 | implementation 'io.netty:netty-all:4.1.100.Final'
39 | implementation 'ch.qos.logback:logback-core:1.4.14'
40 | implementation 'ch.qos.logback:logback-classic:1.4.12'
41 | implementation 'org.slf4j:slf4j-api:2.0.7'
42 | implementation 'org.yaml:snakeyaml:2.0'
43 |
44 |
45 | //compile 'netty'
46 | // Declare the dependency for your favourite test framework you want to use in your tests.
47 | // TestNG is also supported by the Gradle Test task. Just change the
48 | // testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
49 | // 'test.useTestNG()' to your build script.
50 | //testCompile 'junit:junit:4.12'
51 | }
52 |
53 | tasks.withType(Javadoc).configureEach {
54 | options.encoding = 'UTF-8'
55 | }
56 |
57 | tasks.register('buildRukkit') {
58 | dependsOn shadowJar
59 | doLast {
60 | println("Okay.Doing last step...")
61 | mkdir("./build/outputs")
62 | /*copy() {
63 | CopySpec copySpec ->
64 | from file("${rootDir}/libs")
65 | into "${rootDir}/build/outputs/libs"
66 | }*/
67 | copy() {
68 | CopySpec copySpec ->
69 | from file("${rootDir}/build/libs/Rukkit-all.jar")
70 | into "${rootDir}/build/outputs/"
71 | rename('Rukkit-all.jar', "Rukkit-${RUKKIT_VERSION}.jar")
72 | }
73 | copy() {
74 | CopySpec copySpec ->
75 | from file("${rootDir}/start.sh")
76 | into "${rootDir}/build/outputs/"
77 | }
78 | copy() {
79 | CopySpec copySpec ->
80 | from file("${rootDir}/start.bat")
81 | into "${rootDir}/build/outputs/"
82 | }
83 | replaceFileText(new File("${rootDir}/build/outputs/start.sh"), "\\{version\\}", RUKKIT_VERSION)
84 | replaceFileText(new File("${rootDir}/build/outputs/start.bat"), "\\{version\\}", RUKKIT_VERSION)
85 | println("""
86 | -- Well done! --
87 | targetRukkitVersion: ${RUKKIT_VERSION}
88 | Check the build/outputs to get the result.
89 | """)
90 | }
91 | }
92 |
93 | static def replaceFileText(file, oldText, newText) {
94 | String text = file.text.replaceAll(oldText, newText)
95 | file.withPrintWriter { printWriter ->
96 | printWriter.print(text)
97 | }
98 | }
99 |
100 |
101 | jar {
102 | manifest {
103 | attributes 'Main-Class': 'cn.rukkit.RukkitLauncher'
104 | }
105 | }
106 |
107 | shadowJar {
108 |
109 | }
110 |
111 | run {}
112 |
113 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RukkitDev/Rukkit/4764085cda35428fe920ecbd0fbc2fd70c6f72b2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2020-2022 RukkitDev Team and contributors.
3 | #
4 | # This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | # 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | #
7 | # https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | #
9 |
10 | #
11 | # Copyright 2020-2022 RukkitDev Team and contributors.
12 | #
13 |
14 | distributionBase=GRADLE_USER_HOME
15 | distributionPath=wrapper/dists
16 | zipStoreBase=GRADLE_USER_HOME
17 | zipStorePath=wrapper/dists
18 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
19 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2020-2022 RukkitDev Team and contributors.
5 | #
6 | # This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
7 | # 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
8 | #
9 | # https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
10 | #
11 |
12 | #
13 | # Copyright 2020-2022 RukkitDev Team and contributors.
14 | #
15 |
16 | ##############################################################################
17 | ##
18 | ## Gradle start up script for UN*X
19 | ##
20 | ##############################################################################
21 |
22 | # Attempt to set APP_HOME
23 | # Resolve links: $0 may be a link
24 | PRG="$0"
25 | # Need this for relative symlinks.
26 | while [ -h "$PRG" ] ; do
27 | ls=`ls -ld "$PRG"`
28 | link=`expr "$ls" : '.*-> \(.*\)$'`
29 | if expr "$link" : '/.*' > /dev/null; then
30 | PRG="$link"
31 | else
32 | PRG=`dirname "$PRG"`"/$link"
33 | fi
34 | done
35 | SAVED="`pwd`"
36 | cd "`dirname \"$PRG\"`/" >/dev/null
37 | APP_HOME="`pwd -P`"
38 | cd "$SAVED" >/dev/null
39 |
40 | APP_NAME="Gradle"
41 | APP_BASE_NAME=`basename "$0"`
42 |
43 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
44 | DEFAULT_JVM_OPTS=""
45 |
46 | # Use the maximum available, or set MAX_FD != -1 to use that value.
47 | MAX_FD="maximum"
48 |
49 | warn () {
50 | echo "$*"
51 | }
52 |
53 | die () {
54 | echo
55 | echo "$*"
56 | echo
57 | exit 1
58 | }
59 |
60 | # OS specific support (must be 'true' or 'false').
61 | cygwin=false
62 | msys=false
63 | darwin=false
64 | nonstop=false
65 | case "`uname`" in
66 | CYGWIN* )
67 | cygwin=true
68 | ;;
69 | Darwin* )
70 | darwin=true
71 | ;;
72 | MINGW* )
73 | msys=true
74 | ;;
75 | NONSTOP* )
76 | nonstop=true
77 | ;;
78 | esac
79 |
80 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
81 |
82 | # Determine the Java command to use to start the JVM.
83 | if [ -n "$JAVA_HOME" ] ; then
84 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
85 | # IBM's JDK on AIX uses strange locations for the executables
86 | JAVACMD="$JAVA_HOME/jre/sh/java"
87 | else
88 | JAVACMD="$JAVA_HOME/bin/java"
89 | fi
90 | if [ ! -x "$JAVACMD" ] ; then
91 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
92 |
93 | Please set the JAVA_HOME variable in your environment to match the
94 | location of your Java installation."
95 | fi
96 | else
97 | JAVACMD="java"
98 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
99 |
100 | Please set the JAVA_HOME variable in your environment to match the
101 | location of your Java installation."
102 | fi
103 |
104 | # Increase the maximum file descriptors if we can.
105 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
106 | MAX_FD_LIMIT=`ulimit -H -n`
107 | if [ $? -eq 0 ] ; then
108 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
109 | MAX_FD="$MAX_FD_LIMIT"
110 | fi
111 | ulimit -n $MAX_FD
112 | if [ $? -ne 0 ] ; then
113 | warn "Could not set maximum file descriptor limit: $MAX_FD"
114 | fi
115 | else
116 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
117 | fi
118 | fi
119 |
120 | # For Darwin, add options to specify how the application appears in the dock
121 | if $darwin; then
122 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
123 | fi
124 |
125 | # For Cygwin, switch paths to Windows format before running java
126 | if $cygwin ; then
127 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
128 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
129 | JAVACMD=`cygpath --unix "$JAVACMD"`
130 |
131 | # We build the pattern for arguments to be converted via cygpath
132 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
133 | SEP=""
134 | for dir in $ROOTDIRSRAW ; do
135 | ROOTDIRS="$ROOTDIRS$SEP$dir"
136 | SEP="|"
137 | done
138 | OURCYGPATTERN="(^($ROOTDIRS))"
139 | # Add a user-defined pattern to the cygpath arguments
140 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
141 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
142 | fi
143 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
144 | i=0
145 | for arg in "$@" ; do
146 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
147 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
148 |
149 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
150 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
151 | else
152 | eval `echo args$i`="\"$arg\""
153 | fi
154 | i=$((i+1))
155 | done
156 | case $i in
157 | (0) set -- ;;
158 | (1) set -- "$args0" ;;
159 | (2) set -- "$args0" "$args1" ;;
160 | (3) set -- "$args0" "$args1" "$args2" ;;
161 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
162 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
163 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
164 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
165 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
166 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
167 | esac
168 | fi
169 |
170 | # Escape application args
171 | save () {
172 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
173 | echo " "
174 | }
175 | APP_ARGS=$(save "$@")
176 |
177 | # Collect all arguments for the java command, following the shell quoting and substitution rules
178 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
179 |
180 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
181 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
182 | cd "$(dirname "$0")"
183 | fi
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/rukkit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RukkitDev/Rukkit/4764085cda35428fe920ecbd0fbc2fd70c6f72b2/rukkit.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This settings file was generated by the Gradle 'init' task.
3 | *
4 | * The settings file is used to specify which projects to include in your build.
5 | * In a single project build this file can be empty or even removed.
6 | *
7 | * Detailed information about configuring a multi-project build in Gradle can be found
8 | * in the user guide at https://docs.gradle.org/4.4.1/userguide/multi_project_builds.html
9 | */
10 |
11 | /*
12 | // To declare projects as part of a multi-project build use the 'include' method
13 | include 'shared'
14 | include 'api'
15 | include 'services:webservice'
16 | */
17 |
18 | rootProject.name = 'Rukkit'
19 | ext {
20 | rukkitVersion = '0.8.0'
21 | supportGameVersion = '151'
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/Launsjsnsnsn.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit;
11 |
12 | public class Launsjsnsnsn
13 | {
14 | public static void start(String args[]) {
15 | // fuck!
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/RukkitLauncher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit;
11 |
12 | import ch.qos.logback.classic.layout.TTLLLayout;
13 | import ch.qos.logback.classic.spi.ILoggingEvent;
14 | import ch.qos.logback.core.ConsoleAppender;
15 | import ch.qos.logback.core.Layout;
16 | import cn.rukkit.command.ServerCommandCompleter;
17 | import io.netty.util.internal.logging.InternalLoggerFactory;
18 | import io.netty.util.internal.logging.Slf4JLoggerFactory;
19 | import org.jline.reader.EndOfFileException;
20 | import org.jline.reader.LineReader;
21 | import org.jline.reader.LineReaderBuilder;
22 | import org.jline.reader.UserInterruptException;
23 | import org.jline.reader.impl.completer.ArgumentCompleter;
24 | import org.jline.reader.impl.completer.NullCompleter;
25 | import org.jline.terminal.Terminal;
26 | import org.jline.terminal.TerminalBuilder;
27 | import org.slf4j.Logger;
28 | import org.slf4j.LoggerFactory;
29 |
30 | import java.io.IOException;
31 |
32 | public class RukkitLauncher extends ConsoleAppender
33 | {
34 | static Terminal terminal;
35 | static LineReader lineReader;
36 | public static final String PATTERN = ">";
37 | static Thread terminalThread;
38 | static boolean isTerminalRunning = true;
39 |
40 | public static ServerCommandCompleter serverCommandCompleter = new ServerCommandCompleter();
41 |
42 | private static Logger log = LoggerFactory.getLogger("Launcher");
43 | public static void main(String args[]){
44 | InternalLoggerFactory.setDefaultFactory(new Slf4JLoggerFactory());
45 | try {
46 | log.info("init::JLine Terminal...");
47 | terminal = TerminalBuilder.builder().system(true).jna(true).build();
48 | lineReader = LineReaderBuilder.builder().terminal(terminal).completer(new ArgumentCompleter(
49 | serverCommandCompleter,
50 | NullCompleter.INSTANCE
51 | )).build();
52 | Rukkit.startServer();
53 | while (isTerminalRunning) {
54 | try {
55 | Thread.sleep(1); // 不知道为什么反正要这个东西
56 | if (Rukkit.getCommandManager() == null) continue;
57 | if (Rukkit.isStarted()) {
58 | serverCommandCompleter.setCommandCompleteVars(Rukkit.getCommandManager().getLoadedServerCommandStringList());
59 | } else {
60 | continue;
61 | }
62 | String str = lineReader.readLine(PATTERN);
63 | Rukkit.getCommandManager().executeServerCommand(str);
64 | }
65 | catch (UserInterruptException e) {
66 | log.info("Stopping server...");
67 | Rukkit.shutdown("Server stopped by console");
68 | }
69 | catch (EndOfFileException e) {
70 | log.info("Stopping server...");
71 | Rukkit.shutdown("Server stopped by console");
72 | break;
73 | }
74 | catch (Exception e) {
75 | System.out.println("Oops.A exception occurred.");
76 | e.printStackTrace();
77 | }
78 | }
79 | } catch (IOException e) {
80 | //e.printStackTrace();
81 | } catch (InterruptedException e) {
82 | //e.printStackTrace();
83 | }
84 | }
85 |
86 | Layout layout = new TTLLLayout();
87 |
88 | private static void nop() {}
89 |
90 |
91 | @Override
92 | public void start() {
93 | super.start();
94 | layout.start();
95 | }
96 |
97 | @Override
98 | public void stop() {
99 | layout.stop();
100 | super.stop();
101 | }
102 |
103 | @Override
104 | protected void subAppend(ILoggingEvent event) {
105 | lineReader.printAbove(new String(encoder.encode(event)));
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/ChatCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 | import cn.rukkit.plugin.*;
12 |
13 | public class ChatCommand
14 | {
15 | public String cmd;
16 | public String helpMessage;
17 | public int args = 1;
18 | public boolean adminRequired = false;
19 | private boolean isEnabled = false;
20 | private ChatCommandListener chatListener;
21 | private RukkitPlugin fromPlugin;
22 |
23 |
24 | public ChatCommand(String msg, String helpMessage,int args, ChatCommandListener chatListener, RukkitPlugin fromPlugin) {
25 | this.cmd = msg;
26 | this.args = args;
27 | this.helpMessage = helpMessage;
28 | this.chatListener = chatListener;
29 | this.fromPlugin = fromPlugin;
30 | }
31 |
32 | public ChatCommand(String msg, String helpMessage,int args, ChatCommandListener chatListener, RukkitPlugin fromPlugin, boolean adminRequired) {
33 | this.cmd = msg;
34 | this.args = args;
35 | this.helpMessage = helpMessage;
36 | this.chatListener = chatListener;
37 | this.fromPlugin = fromPlugin;
38 | this.adminRequired = adminRequired;
39 | }
40 |
41 | public RukkitPlugin getFromPlugin() {
42 | return fromPlugin;
43 | }
44 |
45 | public void setEnabled(boolean isEnabled) {
46 | this.isEnabled = isEnabled;
47 | }
48 |
49 | public boolean isEnabled() {
50 | return isEnabled;
51 | }
52 |
53 | public void setListener(ChatCommandListener listener) {
54 | this.chatListener = listener;
55 | }
56 |
57 | public ChatCommandListener getListener() {
58 | return chatListener;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/ChatCommandListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 | import cn.rukkit.network.*;
12 |
13 | public interface ChatCommandListener
14 | {
15 | public boolean onSend(RoomConnection con, String args[]);
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/Command.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 | import cn.rukkit.plugin.*;
12 |
13 | public class Command
14 | {
15 | public enum CommandType {
16 | CHAT, SERVER, BOTH
17 | }
18 | public String cmd;
19 | public String helpMessage;
20 | public int args = 1;
21 | private boolean isEnabled = false;
22 | private ChatCommandListener chatListener;
23 | private RukkitPlugin fromPlugin;
24 | public CommandType type;
25 |
26 | public Command(String msg, String helpMessage,int args, ChatCommandListener chatListener, RukkitPlugin fromPlugin, CommandType type) {
27 | this.cmd = msg;
28 | this.args = args;
29 | this.helpMessage = helpMessage;
30 | this.chatListener = chatListener;
31 | this.fromPlugin = fromPlugin;
32 | }
33 |
34 | public RukkitPlugin getFromPlugin() {
35 | return fromPlugin;
36 | }
37 |
38 | public void setEnabled(boolean isEnabled) {
39 | this.isEnabled = isEnabled;
40 | }
41 |
42 | public boolean isEnabled() {
43 | return isEnabled;
44 | }
45 |
46 | public void setListener(ChatCommandListener listener) {
47 | this.chatListener = listener;
48 | }
49 |
50 | public ChatCommandListener getListener() {
51 | return chatListener;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/CommandHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 |
12 | public class CommandHandler
13 | {
14 | }
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/CommandManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 |
12 | import java.util.*;
13 |
14 | import cn.rukkit.util.LangUtil;
15 | import org.jline.reader.Candidate;
16 | import org.jline.reader.Completer;
17 | import org.jline.reader.LineReader;
18 | import org.jline.reader.ParsedLine;
19 | import org.jline.reader.impl.completer.StringsCompleter;
20 | import org.slf4j.*;
21 | import cn.rukkit.network.*;
22 | import cn.rukkit.*;
23 | import cn.rukkit.network.packet.*;
24 | import java.io.*;
25 |
26 | public class CommandManager
27 | {
28 | private Logger log = LoggerFactory.getLogger(CommandManager.class);
29 | private HashMap loadedCommand = new HashMap();
30 | private HashMap loadedServerCommand = new HashMap();
31 |
32 | private List serverCmdString = new ArrayList<>();
33 |
34 | public void registerCommand(ChatCommand cmd) {
35 | log.debug(String.format("Registering Command '%s' from plugin '%s'...",cmd.cmd,cmd.getFromPlugin().config.name));
36 | if (fetchCommand(cmd.cmd) != null) {
37 | log.warn(String.format("Command '%s' had already registered.",cmd.cmd));
38 | } else {
39 | loadedCommand.put(cmd.cmd, cmd);
40 | }
41 | }
42 |
43 | public void registerServerCommand(ServerCommand cmd) {
44 | log.debug(String.format("Registering ServerCommand '%s' from plugin '%s'...",cmd.cmd,cmd.getFromPlugin().config.name));
45 | if (fetchServerCommand(cmd.cmd) != null) {
46 | log.warn(String.format("ServerCommand '%s' had already registered.",cmd.cmd));
47 | } else {
48 | loadedServerCommand.put(cmd.cmd, cmd);
49 | serverCmdString.add(cmd.cmd);
50 | }
51 | }
52 |
53 | public void executeChatCommand(RoomConnection connection, String cmd) {
54 | String[] cmds = cmd.split("\\s+", 2);
55 | ChatCommand cmdObj = fetchCommand(cmds[0]);
56 | if (cmdObj == null) {
57 | connection.sendServerMessage(LangUtil.getString("chat.invalidCommand"));
58 | return;
59 | } else if (cmdObj.adminRequired){
60 | if (!connection.player.isAdmin) {
61 | connection.sendServerMessage(LangUtil.getString("chat.privDenied"));
62 | return;
63 | }
64 | }
65 | boolean result;
66 | log.trace("cmd is:" + cmds[0]);
67 | if (cmds.length > 1 && cmdObj.args > 0) {
68 | String[] args = cmds[1].split(" ", cmdObj.args);
69 | result = cmdObj.getListener().onSend(connection,args);
70 | } else {
71 | result = cmdObj.getListener().onSend(connection,new String[0]);
72 | }
73 | if (result == true) {
74 | try {
75 | connection.currectRoom.broadcast(
76 | Packet.chat(connection.player.name,
77 | "-" + cmd,
78 | connection.player.playerIndex));
79 | } catch (IOException e) {}
80 | }
81 | }
82 |
83 | public void executeServerCommand(String cmd) {
84 | String[] cmds = cmd.split("\\s+", 2);
85 | ServerCommand cmdObj = fetchServerCommand(cmds[0]);
86 | if (cmdObj == null) {
87 | System.out.println("Command not exist.Try 'help' to list all commands.");
88 | return;
89 | }
90 | log.trace("cmd is:" + cmds[0]);
91 | if (cmds.length > 1 && cmdObj.args > 0) {
92 | String[] args = cmds[1].split(" ", cmdObj.args);
93 | cmdObj.getListener().onSend(args);
94 | } else {
95 | cmdObj.getListener().onSend(new String[0]);
96 | }
97 | }
98 |
99 |
100 | public ChatCommand fetchCommand(String cmd){
101 | return loadedCommand.getOrDefault(cmd, null);
102 | }
103 |
104 | public ServerCommand fetchServerCommand(String cmd) {
105 | return loadedServerCommand.getOrDefault(cmd, null);
106 | }
107 |
108 | public HashMap getLoadedCommand() {
109 | return loadedCommand;
110 | }
111 |
112 | public HashMap getLoadedServerCommand() {
113 | return loadedServerCommand;
114 | }
115 |
116 | public List getLoadedServerCommandStringList() {
117 | return serverCmdString;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/ServerCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 |
12 | import cn.rukkit.plugin.RukkitPlugin;
13 |
14 | public class ServerCommand {
15 | public String cmd;
16 | public String helpMessage;
17 | public int args = 1;
18 | private boolean isEnabled = false;
19 | private ServerCommandListener serverCommandListener;
20 | private RukkitPlugin fromPlugin;
21 |
22 | public ServerCommand(String msg, String helpMessage,int args, ServerCommandListener chatListener, RukkitPlugin fromPlugin) {
23 | this.cmd = msg;
24 | this.args = args;
25 | this.helpMessage = helpMessage;
26 | this.serverCommandListener = chatListener;
27 | this.fromPlugin = fromPlugin;
28 | }
29 |
30 | public RukkitPlugin getFromPlugin() {
31 | return fromPlugin;
32 | }
33 |
34 | public void setEnabled(boolean isEnabled) {
35 | this.isEnabled = isEnabled;
36 | }
37 |
38 | public boolean isEnabled() {
39 | return isEnabled;
40 | }
41 |
42 | public void setListener(ServerCommandListener listener) {
43 | this.serverCommandListener = listener;
44 | }
45 |
46 | public ServerCommandListener getListener() {
47 | return serverCommandListener;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/ServerCommandCompleter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 |
12 | import org.jline.reader.Candidate;
13 | import org.jline.reader.Completer;
14 | import org.jline.reader.LineReader;
15 | import org.jline.reader.ParsedLine;
16 | import org.jline.reader.impl.completer.StringsCompleter;
17 |
18 | import java.util.List;
19 |
20 | public class ServerCommandCompleter implements Completer {
21 |
22 | Completer completer;
23 |
24 | public ServerCommandCompleter() {
25 | this.completer = new StringsCompleter();
26 | }
27 |
28 | @Override
29 | public void complete(LineReader reader, ParsedLine line, List candidates) {
30 | completer.complete(reader, line, candidates);
31 | }
32 |
33 | public void setCommandCompleteVars(List fileVars) {
34 | this.completer = new StringsCompleter(fileVars);
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/ServerCommandListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command;
11 |
12 | public interface ServerCommandListener {
13 | public void onSend(String args[]);
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/command/completer/PlayerCompleter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.command.completer;
11 |
12 | import org.jline.reader.Candidate;
13 | import org.jline.reader.Completer;
14 | import org.jline.reader.LineReader;
15 | import org.jline.reader.ParsedLine;
16 | import org.jline.reader.impl.completer.StringsCompleter;
17 |
18 | import java.util.List;
19 |
20 | public class PlayerCompleter extends StringsCompleter {
21 | Completer completer;
22 |
23 | @Override
24 | public void complete(LineReader reader, ParsedLine commandLine, List candidates) {
25 | StringsCompleter stringsCompleter = new StringsCompleter();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/config/BaseConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.config;
11 |
12 | import cn.rukkit.*;
13 | import java.io.*;
14 | import org.yaml.snakeyaml.*;
15 | //import java.util.logging.*;
16 | import org.slf4j.*;
17 | import org.yaml.snakeyaml.nodes.Tag;
18 |
19 | public abstract class BaseConfig
20 | {
21 | Logger log = LoggerFactory.getLogger(this.getClass());
22 | public String configName;
23 | //public abstract void ConfigFile();
24 | public BaseConfig loadConfig() throws IllegalAccessException, InstantiationException, IOException {
25 | this.getClass().newInstance();
26 | File confFile = new File(Rukkit.getEnvPath() + configName);
27 | if (confFile.exists() && confFile.isFile()) {
28 | log.debug("Found Config file.Reading...");
29 | return new Yaml().loadAs(new FileReader(confFile), this.getClass());
30 | } else {
31 | log.debug("Config file.not found.Creating...");
32 | confFile.delete();
33 | confFile.createNewFile();
34 | BaseConfig cfg = this.getClass().newInstance();
35 | FileWriter writer = new FileWriter(confFile);
36 | writer.write(new Yaml().dumpAs(cfg, Tag.MAP, DumperOptions.FlowStyle.BLOCK));
37 | writer.flush();
38 | writer.close();
39 | return cfg;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/config/RoundConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.config;
11 |
12 | public class RoundConfig extends BaseConfig
13 | {
14 | /*Dynamic Properties*/
15 | public String mapName = "[z;p10]Crossing Large (10p)";
16 | public int mapType = 0;
17 | public float income = 1.0f;
18 | public int credits = 4000;
19 | public boolean disableNuke = true;
20 | public boolean sharedControl = false;
21 | public int fogType = 2;
22 | public int startingUnits = 1;
23 | //public String configName = "round.yml";
24 |
25 | public RoundConfig() {
26 | this.configName = "round.yml";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/config/RukkitConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.config;
11 |
12 | import java.util.Locale;
13 |
14 | public class RukkitConfig extends BaseConfig
15 | {
16 | public String serverUser = "RUKKIT";
17 | public String welcomeMsg = "Welcome to Rukkit server, {playerName}!";
18 | public String serverMotd = "My Rukkit server";
19 | public int serverPort = 5123;
20 | public int maxPlayer = 10;
21 | public int maxRoom = 5;
22 | public int minStartPlayer = 4;
23 | public boolean syncEnabled = true;
24 | public boolean singlePlayerMode = false;
25 | public boolean isDebug = true;
26 | public boolean onlineMode = false;
27 | public String logPath = "/sdcard/rukkit-error.log";
28 | public int maxPacketFrame = 8192;
29 | public String UUID = "00000000-0000-0000-0000-000000000000";
30 | public String lang = Locale.getDefault().toString();
31 | //max threads in manager.Default = 8;
32 | public int threadPoolCount = 8;
33 | // max unit in per player 单玩家最大单位
34 | public int maxUnitsPerPlayer = 250;
35 | // using question system to vote 投票系统使用提示框模式实现
36 | // public boolean usingPopupInVote = false;
37 |
38 | //Ping packet receive timeout.default = 8000 (ms)
39 | public int pingTimeout = 8000;
40 |
41 | //registerTimeout default = 5 (s)
42 | public int registerTimeout = 5;
43 |
44 | //Using commandQuere to manage game commands
45 | public boolean useCommandQuere = false;
46 |
47 | public boolean checksumSync = false;
48 |
49 | public RukkitConfig() {
50 | this.configName = "rukkit.yml";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/Cancellable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event;
11 |
12 | public interface Cancellable
13 | {
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/Event.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event;
11 |
12 | public class Event
13 | {
14 | public boolean isCancelled = false;
15 |
16 | public void setCancel(boolean cancel) {
17 | if (this instanceof Cancellable) {
18 | this.isCancelled = cancel;
19 | } else {
20 | //throw new RuntimeException("Event not cancellable");
21 | //Do nothing.
22 | }
23 | }
24 |
25 | public boolean isCancelled() {
26 | if (this instanceof Cancellable) {
27 | return isCancelled;
28 | } else {
29 | //throw new RuntimeException("Event not cancellable");
30 | return false;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/EventHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event;
11 |
12 | import java.lang.annotation.*;
13 |
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface EventHandler
16 | {
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/EventListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event;
11 |
12 | public interface EventListener
13 | {
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/EventListenerContainer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event;
11 |
12 | import cn.rukkit.plugin.*;
13 | import java.lang.reflect.*;
14 | import java.util.*;
15 |
16 | public class EventListenerContainer
17 | {
18 | public Method method;
19 | public RukkitPlugin plugin;
20 | public EventListener listener;
21 | public EventListenerContainer(RukkitPlugin plugin, Method method, EventListener listener){
22 | this.method = method;
23 | this.listener = listener;
24 | this.plugin = plugin;
25 | }
26 |
27 | public Event callMethod(Event event) {
28 | method.setAccessible(true);
29 | try
30 | {
31 | method.invoke(listener, event);
32 | //listener.invoke(new PlayerJoinEvent(), new PlayerJoinEvent());
33 | }
34 | catch (IllegalAccessException e)
35 | {
36 | e.printStackTrace();
37 | }
38 | catch (IllegalArgumentException e)
39 | {
40 | e.printStackTrace();
41 | }
42 | catch (InvocationTargetException e)
43 | {
44 | e.printStackTrace();
45 | }
46 | return event;
47 | }
48 |
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/ListenerList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event;
11 |
12 | import cn.rukkit.event.*;
13 | import java.util.*;
14 | import cn.rukkit.util.*;
15 | import org.slf4j.*;
16 | import cn.rukkit.plugin.RukkitPlugin;
17 |
18 | public class ListenerList
19 | {
20 | private Class eventClass;
21 | private static Logger log;
22 | private ArrayList listenerList = new ArrayList();
23 |
24 | public ListenerList(Class clazz) {
25 | this.eventClass = clazz;
26 | this.log = LoggerFactory.getLogger("List" + eventClass.toString());
27 | }
28 |
29 | public void registerListener(EventListenerContainer listener) {
30 | this.listenerList.add(listener);
31 | }
32 |
33 | public boolean callListeners(Event event) {
34 | for(EventListenerContainer listener : listenerList) {
35 | Event e = listener.callMethod(event);
36 | log.debug("isCanceled: " + e.isCancelled);
37 | if (e.isCancelled) {
38 | return false;
39 | }
40 | }
41 | return true;
42 | }
43 |
44 | public void removePluginListener(EventListener listener) {
45 | // 更安全的移除
46 | Iterator iterator = listenerList.iterator();
47 | while (iterator.hasNext()) {
48 | EventListenerContainer container = iterator.next();
49 | if (container.listener.getClass() == listener.getClass()) {
50 | iterator.remove();
51 | }
52 | }
53 | /*
54 | for (EventListenerContainer c: listenerList) {
55 | if (c.listener.getClass() == listener.getClass()) {
56 | listenerList.remove(c);
57 | }
58 | }*/
59 | }
60 |
61 | public void clear() {
62 | this.listenerList.clear();
63 | }
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/action/ActionEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.action;
11 | import cn.rukkit.event.*;
12 |
13 | public class ActionEvent extends Event
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/action/BuildEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.action;
11 |
12 | import cn.rukkit.event.*;
13 | import cn.rukkit.event.action.*;
14 | import cn.rukkit.game.*;
15 |
16 | public class BuildEvent extends ActionEvent implements Cancellable
17 | {
18 | private static ListenerList list = new ListenerList(BuildEvent.class);
19 |
20 | public static ListenerList getListenerList() {
21 | return list;
22 | }
23 |
24 | private float targetX;
25 |
26 | private float targetY;
27 |
28 | private String targetUnitName;
29 |
30 | private long fromUnitId;
31 | private NetworkPlayer player;
32 |
33 | public float getTargetX()
34 | {
35 | return targetX;
36 | }
37 |
38 | public float getTargetY()
39 | {
40 | return targetY;
41 | }
42 |
43 | public String getTargetUnitName()
44 | {
45 | return targetUnitName;
46 | }
47 |
48 | public long getFromUnitId()
49 | {
50 | return fromUnitId;
51 | }
52 |
53 | public NetworkPlayer getPlayer() {
54 | return this.player;
55 | }
56 |
57 | public BuildEvent (NetworkPlayer p, float targetX, float targetY, long fromUnitId, String targetUnitName) {
58 | this.player = p;
59 | this.targetX = targetX;
60 | this.targetY = targetY;
61 | this.fromUnitId = fromUnitId;
62 | this.targetUnitName = targetUnitName;
63 | }
64 |
65 | public BuildEvent (NetworkPlayer p, float targetX, float targetY, String targetUnitName) {
66 | this.player = p;
67 | this.targetX = targetX;
68 | this.targetY = targetY;
69 | this.fromUnitId = 0;
70 | this.targetUnitName = targetUnitName;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/action/MoveEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.action;
11 |
12 | import cn.rukkit.event.*;
13 | import cn.rukkit.event.action.*;
14 | import cn.rukkit.game.*;
15 |
16 | public class MoveEvent extends ActionEvent implements Cancellable
17 | {
18 | private static ListenerList list = new ListenerList(MoveEvent.class);
19 |
20 | public static ListenerList getListenerList() {
21 | return list;
22 | }
23 |
24 | private NetworkPlayer player;
25 | private float targetX;
26 | private float targetY;
27 | private long actionUnitId;
28 |
29 | public MoveEvent(NetworkPlayer p, float x, float y, long id){
30 | this.player = p;
31 | this.targetX = x;
32 | this.targetY = y;
33 | this.actionUnitId = id;
34 | }
35 |
36 | public MoveEvent(NetworkPlayer p, float x, float y) {
37 | this.player = p;
38 | this.targetX = x;
39 | this.targetY = y;
40 | this.actionUnitId = 0;
41 | }
42 |
43 | public float getTargetX()
44 | {
45 | return targetX;
46 | }
47 |
48 | public float getTargetY()
49 | {
50 | return targetY;
51 | }
52 |
53 | public long getActionUnitId() {
54 | return this.actionUnitId;
55 | }
56 |
57 | public NetworkPlayer getPlayer() {
58 | return this.player;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/action/PingEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.action;
11 |
12 | import cn.rukkit.event.*;
13 | import cn.rukkit.game.*;
14 |
15 | public class PingEvent extends ActionEvent implements Cancellable
16 | {
17 | private static ListenerList list = new ListenerList(PingEvent.class);
18 |
19 | private String pingType;
20 |
21 | public static ListenerList getListenerList() {
22 | return list;
23 | }
24 |
25 | private NetworkPlayer player;
26 | private float targetX;
27 | private float targetY;
28 |
29 | public PingEvent(NetworkPlayer p, float x, float y, String pingType){
30 | this.player = p;
31 | this.targetX = x;
32 | this.targetY = y;
33 | this.pingType = pingType;
34 | }
35 |
36 | public float getTargetX()
37 | {
38 | return targetX;
39 | }
40 |
41 | public float getTargetY()
42 | {
43 | return targetY;
44 | }
45 |
46 | public NetworkPlayer getPlayer() {
47 | return player;
48 | }
49 |
50 | public String getPingType() {
51 | return pingType;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/action/RallyEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.action;
11 |
12 | public class RallyEvent
13 | {
14 | }
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/action/TaskEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.action;
11 |
12 | import cn.rukkit.event.*;
13 | import cn.rukkit.event.action.*;
14 | import cn.rukkit.game.*;
15 |
16 | public class TaskEvent extends ActionEvent implements Cancellable
17 | {
18 | private static ListenerList list = new ListenerList(TaskEvent.class);
19 |
20 | public static ListenerList getListenerList() {
21 | return list;
22 | }
23 |
24 | private NetworkPlayer player;
25 | private String taskString;
26 | private long actionUnitId;
27 | private boolean isCancel = false;
28 |
29 | public TaskEvent(NetworkPlayer p, String task, long id, boolean isCancel) {
30 | this.player = p;
31 | this.taskString = task;
32 | this.actionUnitId = id;
33 | this.isCancel = isCancel;
34 | }
35 |
36 | public TaskEvent(NetworkPlayer p, String task, long id){
37 | this.player = p;
38 | this.taskString = task;
39 | this.actionUnitId = id;
40 | }
41 |
42 | public TaskEvent(NetworkPlayer p, String task) {
43 | this.player = p;
44 | this.taskString = task;
45 | this.actionUnitId = 0;
46 | }
47 |
48 | public String getTaskString() {
49 | return this.taskString;
50 | }
51 |
52 | public long getActionUnitId() {
53 | return this.actionUnitId;
54 | }
55 |
56 | public NetworkPlayer getPlayer() {
57 | return this.player;
58 | }
59 |
60 | public boolean isCancel() {
61 | return isCancel;
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/player/OnPlayerPreRegisterEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.player;
11 |
12 | public class OnPlayerPreRegisterEvent
13 | {
14 | }
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/player/PlayerChatEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.player;
11 | import cn.rukkit.event.*;
12 | import cn.rukkit.game.*;
13 |
14 | public class PlayerChatEvent extends PlayerEvent implements Cancellable
15 | {
16 | private static ListenerList list = new ListenerList(PlayerChatEvent.class);
17 |
18 | public static ListenerList getListenerList() {
19 | return list;
20 | }
21 |
22 | private NetworkPlayer player;
23 | private String message;
24 |
25 | public PlayerChatEvent(NetworkPlayer p, String message) {
26 | this.player = p;
27 | this.message = message;
28 | }
29 |
30 | public String getMessage() {
31 | return this.message;
32 | }
33 |
34 | public NetworkPlayer getPlayer() {
35 | return this.player;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/player/PlayerEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.player;
11 | import cn.rukkit.event.*;
12 |
13 | public class PlayerEvent extends Event
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/player/PlayerJoinEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.player;
11 |
12 | import cn.rukkit.event.*;
13 | import cn.rukkit.event.player.*;
14 | import cn.rukkit.game.*;
15 |
16 | public class PlayerJoinEvent extends PlayerEvent
17 | {
18 | private static ListenerList list = new ListenerList(PlayerJoinEvent.class);
19 |
20 | public static ListenerList getListenerList() {
21 | return list;
22 | }
23 |
24 | public PlayerJoinEvent(NetworkPlayer p) {
25 | this.player = p;
26 | }
27 |
28 | private NetworkPlayer player;
29 |
30 | public NetworkPlayer getPlayer()
31 | {
32 | return player;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/player/PlayerLeftEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.player;
11 |
12 | import cn.rukkit.event.*;
13 | import cn.rukkit.event.player.*;
14 | import cn.rukkit.game.*;
15 |
16 | public class PlayerLeftEvent extends PlayerEvent
17 | {
18 | private static ListenerList list = new ListenerList(PlayerLeftEvent.class);
19 |
20 | public static ListenerList getListenerList() {
21 | return list;
22 | }
23 |
24 | public PlayerLeftEvent(NetworkPlayer p, String reason) {
25 | this.player = p;
26 | this.reason = reason;
27 | }
28 |
29 | private NetworkPlayer player;
30 | private String reason;
31 |
32 | public NetworkPlayer getPlayer()
33 | {
34 | return player;
35 | }
36 |
37 | public String getReason() {
38 | return reason;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/player/PlayerReconnectEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | /*
11 | * Copyright 2020-2022 RukkitDev Team and contributors.
12 | */
13 |
14 | package cn.rukkit.event.player;
15 |
16 | import cn.rukkit.event.ListenerList;
17 | import cn.rukkit.game.NetworkPlayer;
18 |
19 | public class PlayerReconnectEvent extends PlayerEvent{
20 | private static ListenerList list = new ListenerList(PlayerReconnectEvent.class);
21 |
22 | public static ListenerList getListenerList() {
23 | return list;
24 | }
25 |
26 | public PlayerReconnectEvent(NetworkPlayer p) {
27 | this.player = p;
28 | }
29 |
30 | private NetworkPlayer player;
31 |
32 | public NetworkPlayer getPlayer()
33 | {
34 | return player;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/room/RoomStartGameEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.room;
11 |
12 | import cn.rukkit.event.Event;
13 | import cn.rukkit.event.ListenerList;
14 | import cn.rukkit.network.NetworkRoom;
15 |
16 | public class RoomStartGameEvent extends Event {
17 | private static ListenerList list = new ListenerList(RoomStartGameEvent.class);
18 |
19 | public static ListenerList getListenerList() {
20 | return list;
21 | }
22 |
23 | private NetworkRoom room;
24 |
25 | public NetworkRoom getRoom() {
26 | return room;
27 | }
28 |
29 | public RoomStartGameEvent(NetworkRoom room) {
30 | this.room = room;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/room/RoomStopGameEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.event.room;
11 |
12 | import cn.rukkit.event.Event;
13 | import cn.rukkit.event.ListenerList;
14 | import cn.rukkit.network.NetworkRoom;
15 |
16 | public class RoomStopGameEvent extends Event {
17 | private static ListenerList list = new ListenerList(RoomStopGameEvent.class);
18 |
19 | public static ListenerList getListenerList() {
20 | return list;
21 | }
22 |
23 | private NetworkRoom room;
24 |
25 | public NetworkRoom getRoom() {
26 | return room;
27 | }
28 |
29 | public RoomStopGameEvent(NetworkRoom room) {
30 | this.room = room;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/server/ServerEvent.java:
--------------------------------------------------------------------------------
1 | package cn.rukkit.event.server;
2 |
3 | import cn.rukkit.event.Event;
4 |
5 | public class ServerEvent extends Event {
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/event/server/ServerQuestionRespondEvent.java:
--------------------------------------------------------------------------------
1 | package cn.rukkit.event.server;
2 |
3 | import cn.rukkit.event.ListenerList;
4 | import cn.rukkit.event.player.PlayerChatEvent;
5 | import cn.rukkit.game.NetworkPlayer;
6 |
7 | public class ServerQuestionRespondEvent extends ServerEvent{
8 | private static ListenerList list = new ListenerList(ServerQuestionRespondEvent.class);
9 |
10 | public static ListenerList getListenerList() {
11 | return list;
12 | }
13 |
14 | public ServerQuestionRespondEvent(NetworkPlayer player, int qid, String respondMessage) {
15 | this.player = player;
16 | this.qid = qid;
17 | this.respondMessage = respondMessage;
18 | }
19 |
20 | public NetworkPlayer getPlayer() {
21 | return player;
22 | }
23 |
24 | public int getQid() {
25 | return qid;
26 | }
27 |
28 | public String getRespondMessage() {
29 | return respondMessage;
30 | }
31 |
32 | private NetworkPlayer player;
33 |
34 | private int qid;
35 |
36 | private String respondMessage;
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/CheckSumList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game;
11 |
12 | import org.slf4j.LoggerFactory;
13 |
14 | import java.util.ArrayList;
15 |
16 | public class CheckSumList {
17 | private ArrayList checksumItems = new ArrayList<>();
18 | public class ChecksumItem {
19 | String description;
20 | public long checkData = 0;
21 | public long prefix = 0;
22 | public ChecksumItem(String description) {
23 | this.description = description;
24 | }
25 |
26 | public ChecksumItem(String description, long prefix) {
27 | this(description);
28 | this.prefix = prefix;
29 | }
30 |
31 | public String getDescription() {
32 | return description;
33 | }
34 |
35 | public long getCheckData() {
36 | return checkData;
37 | }
38 |
39 | public void setCheckData(long data) {
40 | this.checkData = data;
41 | }
42 |
43 | @Override
44 | public boolean equals(Object obj) {
45 | if (obj instanceof ChecksumItem item) {
46 | if (Math.abs(item.getCheckData() - getCheckData()) <= prefix) return true;
47 | else return false;
48 | } else {
49 | return false;
50 | }
51 | }
52 | }
53 |
54 | public CheckSumList() {
55 | checksumItems.add(new ChecksumItem("Unit Pos", 100000));
56 | checksumItems.add(new ChecksumItem("Unit Dir", 100000));
57 | checksumItems.add(new ChecksumItem("Unit Hp", 10000));
58 | checksumItems.add(new ChecksumItem("Unit Id", 5));
59 | checksumItems.add(new ChecksumItem("Waypoints", 5));
60 | checksumItems.add(new ChecksumItem("Waypoints Pos", 5));
61 | checksumItems.add(new ChecksumItem("Team Credits", 500));
62 | checksumItems.add(new ChecksumItem("UnitPaths", 5));
63 | checksumItems.add(new ChecksumItem("Unit Count", 10));
64 | checksumItems.add(new ChecksumItem("Team Info", 10));
65 | checksumItems.add(new ChecksumItem("Team 1 Credits", 500));
66 | checksumItems.add(new ChecksumItem("Team 2 Credits", 500));
67 | checksumItems.add(new ChecksumItem("Team 3 Credits", 500));
68 | checksumItems.add(new ChecksumItem("Command center2", 1000));
69 | checksumItems.add(new ChecksumItem("Command center3", 1000));
70 | }
71 |
72 | public ArrayList getCheckList() {
73 | return checksumItems;
74 | }
75 |
76 | public void addCheckItem(ChecksumItem checksumItem) {
77 | checksumItems.add(checksumItem);
78 | }
79 |
80 | public ChecksumItem get(int index) {
81 | return checksumItems.get(index);
82 | }
83 |
84 | public boolean checkData(CheckSumList list) {
85 | int desyncCount = 0;
86 | for (int i = 0;i < checksumItems.size();i++) {
87 | if(!(checksumItems.get(i).equals(list.get(i)))) {
88 | LoggerFactory.getLogger("Checksum").warn("{} {} != {}", checksumItems.get(i).getDescription(),
89 | checksumItems.get(i).getCheckData(), list.get(i).getCheckData());
90 | desyncCount++;
91 | }
92 | }
93 | return desyncCount == 0;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/GameActions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game;
11 |
12 | public enum GameActions
13 | {
14 | MOVE,ATTACK,BUILD,REPAIR,UPLOAD,F,RECLAIM,ATTACK_MOVE,I,PATROL,PROTECT,PRODUCE
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/GlobalPlayerManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game;
11 | import cn.rukkit.*;
12 |
13 | import java.util.Arrays;
14 | //import sun.nio.ch.Net;
15 |
16 | public class GlobalPlayerManager
17 | {
18 | private int max;
19 |
20 | /**
21 | * Init player manager.
22 | * @params maxPlayer set up maxPlayer
23 | */
24 | public GlobalPlayerManager() {
25 | }
26 |
27 | private NetworkPlayer[] players;
28 | //private static Player[] inGamePlayers = new Player[ServerProperties.maxPlayer];
29 |
30 |
31 |
32 | /**
33 | * Get player by index.
34 | */
35 | public NetworkPlayer get(int index){
36 | if (index > players.length - 1) return null;
37 | return players[index];
38 | }
39 |
40 | public NetworkPlayer getPlayerByUUID(String uuid) {
41 | for (NetworkPlayer p: players) {
42 | if (p.uuid.equals(uuid)) {
43 | return p;
44 | }
45 | }
46 | return null;
47 | }
48 |
49 | /**
50 | * get a player index.
51 | */
52 | public int getIndex(NetworkPlayer p){
53 | for(int i=0;i
86 | */
87 | public T getExtraDataAs(String key, T defaultValue, Class tClass) {
88 | return (T) data.extraData.getOrDefault(key, defaultValue);
89 | }
90 |
91 | /**
92 | * 获取玩家的临时数据
93 | * @param key
94 | * @param defaultValue
95 | * @return
96 | */
97 | public Object getTempData(String key, Object defaultValue) {
98 | return data.tempData.getOrDefault(key, defaultValue);
99 | }
100 |
101 | /**
102 | * 放入临时数据
103 | * @param key
104 | * @param value
105 | */
106 | public void putTempData(String key, Object value) {
107 | data.tempData.put(key, value);
108 | }
109 |
110 | public void clearTempData() {
111 | data.tempData = new HashMap();
112 | }
113 |
114 | /**
115 | * Get extra data.
116 | * @param key
117 | * @param defaultValue
118 | * @return
119 | */
120 | public Object getExtraData(String key, Object defaultValue) {
121 | return data.extraData.getOrDefault(key, defaultValue);
122 | }
123 |
124 | /**
125 | * Put a data to player's ExtraData.
126 | * @param key
127 | * @param value
128 | */
129 | public void putExtraData(String key, Object value) {
130 | data.extraData.put(key, value);
131 | }
132 |
133 | /**
134 | * Save player data.
135 | */
136 | public void savePlayerData() {
137 | Yaml yaml = new Yaml(new Constructor(NetworkPlayerData.class, new LoaderOptions()));
138 | try {
139 | FileWriter writer = new FileWriter(Rukkit.getEnvPath() + "/data/player/" + uuid + ".yaml");
140 | writer.write(yaml.dumpAs(data, Tag.MAP, DumperOptions.FlowStyle.BLOCK));
141 | writer.flush();
142 | writer.close();
143 | } catch (FileNotFoundException e) {
144 | //This should NEVER HAPPEN!
145 | } catch (IOException e) {
146 |
147 | }
148 | }
149 |
150 | public void writePlayer(DataOutputStream stream, boolean simpleMode) throws IOException {
151 | if (simpleMode) {
152 | stream.writeByte(0);
153 | stream.writeInt(ping);
154 | stream.writeBoolean(isSharingControl);
155 | stream.writeBoolean(isDisconnected || isAfk);
156 | } else {
157 | //玩家位置
158 | stream.writeByte(playerIndex);
159 | //玩家资金(毫无作用)
160 | stream.writeInt(credits);
161 | //玩家队
162 | stream.writeInt(team);
163 |
164 | stream.writeBoolean(true);
165 |
166 | if(isAdmin){
167 | stream.writeUTF("[[[" + name + "]]]");
168 | }else{
169 | stream.writeUTF(name);
170 | }
171 | stream.writeBoolean(true);
172 |
173 | //enc.stream.writeBoolean(true);
174 | stream.writeInt(ping);
175 | stream.writeLong(System.currentTimeMillis());
176 |
177 | //是否AI
178 | stream.writeBoolean(isAI);
179 | //AI难度
180 | stream.writeInt(0);
181 |
182 | //玩家队伍
183 | stream.writeInt(team);
184 | stream.writeByte(0);
185 |
186 | //分享控制
187 | stream.writeBoolean(isSharingControl);
188 | //是否掉线
189 | stream.writeBoolean(false);
190 |
191 | //是否投降
192 | stream.writeBoolean(isSurrounded);
193 | stream.writeBoolean(false);
194 | stream.writeInt(-9999);
195 |
196 | stream.writeBoolean(false);
197 | //是否房主
198 | stream.writeInt(0);
199 |
200 | // 1.15新增
201 | stream.writeBoolean(false);
202 | stream.writeBoolean(false);
203 | stream.writeBoolean(false);
204 | stream.writeBoolean(false);
205 |
206 | //color
207 | stream.writeInt(playerIndex);
208 | }
209 | }
210 |
211 | public boolean movePlayer(int index){
212 | //If index larger then maxPlayer
213 | if (index > Rukkit.getConfig().maxPlayer) return false;
214 | PlayerManager playerGroup = room.playerManager;
215 | if (!playerGroup.get(index).isEmpty) {
216 | return false;
217 | }
218 | this.playerIndex = index;
219 | playerGroup.remove(this);
220 | playerGroup.set(index, this);
221 | return true;
222 | }
223 |
224 | public boolean moveTeam(int team){
225 | if(team > 9 || team < 0){
226 | return false;
227 | } else {
228 | this.team = team;
229 | }
230 | return true;
231 | }
232 |
233 | public boolean giveAdmin(int index){
234 | NetworkPlayer player = room.playerManager.get(index);
235 | if(index < Rukkit.getConfig().maxPlayer && index >= 0 && !player.isEmpty && this.isAdmin){
236 | player.isAdmin = true;
237 | this.isAdmin = false;
238 | return true;
239 | }
240 | return false;
241 | }
242 |
243 | public void updateServerInfo() {
244 | try {
245 | connection.handler.ctx.writeAndFlush(Packet.serverInfo(room.config, isAdmin));
246 | } catch (IOException e) {}
247 | }
248 |
249 | public void sendTeamMessage(String message) {
250 | for (RoomConnection conn: room.connectionManager.getConnections()) {
251 | if (team == conn.player.team) {
252 | conn.sendMessage(name,
253 | LangUtil.getString("chat.teamMsg") + " " + message,
254 | playerIndex);
255 | }
256 | }
257 | }
258 |
259 | @Override
260 | public String toString() {
261 | return "NetworkPlayer{" +
262 | "name='" + name + '\'' +
263 | ", uuid='" + uuid + '\'' +
264 | ", team=" + team +
265 | ", playerIndex=" + playerIndex +
266 | ", ping=" + ping +
267 | ", isAdmin=" + isAdmin +
268 | ", isSharingControl=" + isSharingControl +
269 | ", isSurrounded=" + isSurrounded +
270 | '}';
271 | }
272 |
273 | public boolean isNull() {
274 | return false;
275 | }
276 |
277 | public static final void initPlayerDataDir() {
278 | File dataDir = new File(Rukkit.getEnvPath() + "/data");
279 | if (!dataDir.isDirectory()) {
280 | dataDir.delete();
281 | dataDir.mkdir();
282 | }
283 | File userDataDir = new File(Rukkit.getEnvPath() + "/data/player");
284 | if (!userDataDir.isDirectory()) {
285 | userDataDir.delete();
286 | userDataDir.mkdir();
287 | }
288 | }
289 |
290 | public void loadPlayerData() {
291 | Logger log = LoggerFactory.getLogger("PlayerData");
292 | log.debug("Load player infomation.");
293 | Yaml yaml = new Yaml(new Constructor(NetworkPlayerData.class, new LoaderOptions()));
294 | File dataFile = new File(Rukkit.getEnvPath() + "/data/player/" + uuid + ".yaml");
295 | try {
296 | if (dataFile.exists()) {
297 | log.debug("Player exists.Loading...");
298 | data = yaml.load(new FileInputStream(dataFile));
299 | data.lastUsedName = name;
300 | data.lastConnectedTime = new Date().toString();
301 | data.lastConnectedAddress = connection.handler.ctx.channel().remoteAddress().toString();
302 | Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dataFile), StandardCharsets.UTF_8));
303 | writer.write(yaml.dumpAs(data, Tag.MAP, DumperOptions.FlowStyle.BLOCK));
304 | writer.flush();
305 | writer.close();
306 | } else {
307 | log.info("New player.Creating data file...");
308 | dataFile.createNewFile();
309 | data = new NetworkPlayerData();
310 | data.uuid = uuid;
311 | data.lastUsedName = name;
312 | data.lastConnectedTime = new Date().toString();
313 | data.lastConnectedAddress = connection.handler.ctx.channel().remoteAddress().toString();
314 | Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dataFile), StandardCharsets.UTF_8));
315 | writer.write(yaml.dumpAs(data, Tag.MAP, DumperOptions.FlowStyle.BLOCK));
316 | writer.flush();
317 | writer.close();
318 | }
319 | } catch (FileNotFoundException ignored) {
320 | // Never happen!
321 | } catch (IOException e) {
322 |
323 | }
324 | }
325 | }
326 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/NetworkPlayerData.java:
--------------------------------------------------------------------------------
1 | package cn.rukkit.game;
2 |
3 | import java.util.HashMap;
4 |
5 | public class NetworkPlayerData {
6 | public String lastUsedName;
7 | public String uuid;
8 | public String lastConnectedTime;
9 |
10 | public String lastConnectedAddress;
11 | public HashMap extraData = new HashMap();
12 | public HashMap tempData = new HashMap();
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/PingType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game;
11 |
12 | public enum PingType {
13 | normal,
14 | attack,
15 | defend,
16 | nuke,
17 | build,
18 | upgrade,
19 | ok,
20 | no,
21 | happy,
22 | sad,
23 | retreats
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/PlayerManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game;
11 | import cn.rukkit.*;
12 | import cn.rukkit.network.NetworkRoom;
13 |
14 | import java.util.Arrays;
15 | //import sun.nio.ch.Net;
16 |
17 | public class PlayerManager
18 | {
19 | private int max;
20 | private NetworkRoom currentRoom;
21 |
22 | /**
23 | * Init player manager.
24 | * @params maxPlayer set up maxPlayer
25 | */
26 | public PlayerManager(NetworkRoom room, int maxPlayer) {
27 | this.max = maxPlayer;
28 | currentRoom = room;
29 | reset();
30 | }
31 |
32 | private volatile NetworkPlayer[] players;
33 | //private static Player[] inGamePlayers = new Player[ServerProperties.maxPlayer];
34 |
35 | /**
36 | * Add a player into Array.
37 | */
38 | public int add(NetworkPlayer p) {
39 | for(int i=0;i players.length - 1) return null;
94 | return players[index];
95 | }
96 |
97 | public NetworkPlayer getPlayerByUUID(String uuid) {
98 | for (NetworkPlayer p: players) {
99 | if (p.uuid.equals(uuid)) {
100 | return p;
101 | }
102 | }
103 | return null;
104 | }
105 |
106 | /**
107 | * get a player index.
108 | */
109 | public int getIndex(NetworkPlayer p){
110 | for(int i=0;i= 5) {
40 | log.debug("" + in.readBoolean());
41 | }
42 | if (version >= 23) {
43 | in.startBlock(true);
44 |
45 | if (version >= 54) {
46 | log.debug("{}, {}", in.readString(), in.readInt());
47 | log.debug("{}, {}", in.readString(), in.readInt());
48 | int basic, maxunit;
49 | log.debug("Basic={}, MaxUnit={}", basic = in.readInt(), maxunit = in.readInt());
50 | for (int i = basic;i <= maxunit;i++) {
51 | log.debug("Unit: {} (id={})", in.readString(), in.readInt());
52 | in.readBoolean();
53 | if (in.readBoolean()) {
54 | log.debug("From MOD:{}", in.readString());
55 | }
56 | in.readLong();in.readLong();
57 | }
58 | }
59 |
60 | if (version >= 56) {
61 | /*log.debug("{}, {}", in.readString(), in.readInt());
62 | if (in.readBoolean()) {
63 | in.readInt();
64 | log.debug("{}, {}, {}, {}, {}, {}, {}, {}, {}"
65 | ,in.readInt(), in.readInt(), in.readBoolean(),
66 | in.readInt(), in.readInt(), in.readFloat(),
67 | in.readBoolean(), in.readBoolean(), in.readBoolean());
68 | }*/
69 | in.getDecodeBytes();
70 | }
71 |
72 | log.debug("MapPath={}", in.readString());
73 |
74 | if (version >= 73 && in.readBoolean()) {
75 | in.readStreamBytes();
76 | }
77 |
78 | int tickTime;
79 | float mapX, mapY;
80 |
81 | log.debug("{}, {}, {}, {}",
82 | tickTime = in.readInt(), mapY = in.readFloat(), mapX = in.readFloat(), in.readFloat());
83 |
84 | this.time = tickTime;
85 |
86 | log.debug("{}, {}",
87 | in.readInt(), in.readInt());
88 |
89 | log.debug("Setup ended(Mark={}).", in.readShort());
90 |
91 | /*if (in.readBoolean()) {
92 | int x = in.readInt();
93 | int y = in.readInt();
94 | for (int i=0;i= 86) {
102 | log.debug("{}, {}, {}, {}",
103 | in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean());
104 | }
105 |
106 | if (in.readBoolean()) {
107 |
108 | }*/
109 | }
110 | }
111 |
112 | public void dumpToFile(File f) throws IOException {
113 | if (!f.exists()) f.createNewFile();
114 | FileOutputStream out = new FileOutputStream(f);
115 | out.write(arr);
116 | out.flush();
117 | }
118 |
119 | @Deprecated
120 | public void writeInjectedData(GameOutputStream out) throws IOException {
121 | GameInputStream in = new GameInputStream(arr);
122 | //GameOutputStream out = new GameOutputStream();
123 | log.debug("{}, {}", in.readString(), in.readInt());
124 | //out.writeString("Fuck You outputstream!!!!!!");
125 | out.startBlock("gameSave", false);
126 | int version;
127 | //log.debug("Save Header: {}", in.readString());
128 | out.writeString(in.readString()); // Header
129 | out.writeInt(in.readInt());
130 | log.debug("Save Version: {}", version = in.readInt());
131 | //version = 90;
132 | out.writeInt(version);
133 | if (version >= 5) {
134 | out.writeBoolean(in.readBoolean());
135 | }
136 | if (version >= 23) {
137 | in.startBlock(true);
138 | out.startBlock("saveCompression", true);
139 |
140 | if (version >= 54) {
141 | out.startBlock("customUnitsBlock", false);
142 | out.startBlock("customUnits", false);
143 | int basic, maxunit;
144 | log.debug("Basic={}, MaxUnit={}", basic = in.readInt(), maxunit = in.readInt());
145 | out.writeInt(basic);
146 | out.writeInt(maxunit);
147 | for (int i = basic;i <= maxunit;i++) {
148 | //log.debug("Unit: {} (id={})", in.readString(), in.readInt());
149 | String name = in.readString();
150 | log.debug("U: {}", name);
151 | out.writeString(name);
152 | out.writeInt(in.readInt());
153 | out.writeBoolean(in.readBoolean());
154 | if (in.readBoolean()) {
155 | out.writeBoolean(true);
156 | //log.debug("From MOD:{}", in.readString());
157 | out.writeString(in.readString());
158 | }
159 | out.writeLong(in.readLong());
160 | out.writeLong(in.readLong());
161 | }
162 | out.endBlock();
163 | out.endBlock();
164 | }
165 |
166 | if (version >= 56) {
167 | /*log.debug("{}, {}", in.readString(), in.readInt());
168 | if (in.readBoolean()) {
169 | in.readInt();
170 | log.debug("{}, {}, {}, {}, {}, {}, {}, {}, {}"
171 | ,in.readInt(), in.readInt(), in.readBoolean(),
172 | in.readInt(), in.readInt(), in.readFloat(),
173 | in.readBoolean(), in.readBoolean(), in.readBoolean());
174 | }*/
175 | out.startBlock("gameSetup", false);
176 | }
177 |
178 | String mapPath = in.readString();
179 | log.debug("MapPath={}", mapPath);
180 |
181 |
182 | if (version >= 73 && in.readBoolean()) {
183 | in.readStreamBytes();
184 | }
185 |
186 | if (Rukkit.getRoundConfig().mapType == 1) {
187 | mapPath = Rukkit.getRoundConfig().mapName + ".tmx";
188 | out.writeString(mapPath);
189 | out.writeBoolean(true);
190 | out.writeFile(CustomMapLoader.getStreamByName(Rukkit.getRoundConfig().mapName + ".tmx"));
191 | } else {
192 | out.writeString(mapPath);
193 | out.writeBoolean(false);
194 | }
195 |
196 | // Block saveCompression
197 | byte[] cArr = new byte[in.stream.available()];
198 | in.stream.read(cArr);
199 | out.stream.write(cArr);
200 | in.endBlock();
201 | out.endBlock();
202 |
203 | // Block gameSave
204 | cArr = new byte[in.stream.available()];
205 | in.stream.read(cArr);
206 | out.stream.write(cArr);
207 | out.endBlock();
208 | }
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/SaveManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game;
11 | import cn.rukkit.Rukkit;
12 | import cn.rukkit.game.SaveManager;
13 | import java.io.File;
14 | import java.io.FileInputStream;
15 | import java.io.FileNotFoundException;
16 | import java.io.FileOutputStream;
17 | import java.io.IOException;
18 |
19 | import cn.rukkit.network.NetworkRoom;
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 | import cn.rukkit.network.packet.Packet;
23 | import java.io.InputStream;
24 |
25 | public class SaveManager {
26 |
27 | public SaveData lastSave;
28 | public NetworkRoom currentRoom;
29 | private Logger log;
30 |
31 | public SaveManager(NetworkRoom room) {
32 | currentRoom = room;
33 | log = LoggerFactory.getLogger("SaveManager Room #" + currentRoom.roomId);
34 | }
35 |
36 | public SaveData getDeafultSave() {
37 | return Rukkit.getDefaultSave();
38 | }
39 |
40 | public SaveData getLastSave() {
41 | return lastSave;
42 | }
43 |
44 | public void sendDefaultSaveToAll(boolean isPullSave) throws IOException {
45 | currentRoom.broadcast(Packet.sendSave(currentRoom, getDeafultSave().arr, isPullSave));
46 | }
47 |
48 | public void sendLastSaveToAll(boolean isPullSave) throws IOException {
49 | if (lastSave != null) {
50 | currentRoom.broadcast(Packet.sendSave(currentRoom, lastSave.arr,isPullSave));
51 | } else {
52 | log.error("lastSave is NULL!Ignoring sendLastSaveToAll.");
53 | }
54 | }
55 |
56 | public void setLastSave(SaveData save) {
57 | lastSave = save;
58 | }
59 |
60 |
61 | public void dumpLastSave(String filename) throws FileNotFoundException, IOException {
62 | File f = new File(Rukkit.getEnvPath() + "/" + filename);
63 | if (!f.exists()) f.createNewFile();
64 | FileOutputStream out = new FileOutputStream(f);
65 | if (lastSave != null) {
66 | out.write(lastSave.arr);
67 | out.flush();
68 | out.close();
69 | } else {
70 | log.error("lastSave is NULL!Ignore dump request.");
71 | //throw new NullPointerException();
72 | }
73 | }
74 |
75 | public static SaveData readSaveFromFile(String filename) throws FileNotFoundException, IOException {
76 | FileInputStream in = new FileInputStream(filename);
77 | byte[] data = new byte[in.available()];
78 | in.read(data);
79 | in.close();
80 | SaveData save = new SaveData();
81 | save.arr = data;
82 | save.time = 0;
83 | return save;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/UnitType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game;
11 |
12 | public enum UnitType{
13 | NONE,LAND,BUILDING,AIR,WATER,HOVER,OVER_CLIFF,OVER_CLIFF_WATER
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/map/CustomMapLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game.map;
11 |
12 | import cn.rukkit.Rukkit;
13 | import org.slf4j.Logger;
14 | import org.slf4j.LoggerFactory;
15 |
16 | import java.io.File;
17 | import java.io.FileInputStream;
18 | import java.io.FileNotFoundException;
19 | import java.util.ArrayList;
20 |
21 | public class CustomMapLoader {
22 | private static String MAP_FOLDER = Rukkit.getEnvPath() + "/maps";
23 | private static final Logger log = LoggerFactory.getLogger(CustomMapLoader.class);
24 |
25 | public static boolean createDir(){
26 | File folder = new File(MAP_FOLDER);
27 | folder.mkdir();
28 | if(!folder.isDirectory()){
29 | log.warn("Not a dir.Change a another dir...");
30 | MAP_FOLDER = MAP_FOLDER + "_rukkit";
31 | folder = new File(MAP_FOLDER);
32 | folder.mkdir();
33 | if(!folder.exists() || !folder.isDirectory()){
34 | log.error("Load failed.Stop working.");
35 | return false;
36 | }
37 | }
38 | return true;
39 | }
40 |
41 | public static ArrayList getMapList(){
42 | File folder = new File(MAP_FOLDER);
43 | ArrayList list = new ArrayList();
44 | for(String f: folder.list()){
45 | String[] n = f.split("\\.");
46 | if(n[n.length - 1].equals("tmx")){
47 | list.add(f);
48 | }
49 | }
50 | return list;
51 | }
52 |
53 | public static ArrayList getMapNameList(){
54 | File folder = new File(MAP_FOLDER);
55 | ArrayList list = new ArrayList();
56 | for(String f: folder.list()){
57 | String[] n = f.split("\\.");
58 | if(n[n.length - 1].equals("tmx")){
59 | StringBuffer sbf = new StringBuffer();
60 | for(int i = 0;i < n.length -1;i++){
61 | sbf.append(n[i]);
62 | }
63 | list.add(sbf.toString());
64 | }
65 | }
66 | return list;
67 | }
68 |
69 | public static FileInputStream getStreamById(int id) throws FileNotFoundException {
70 | return new FileInputStream(getMapList().get(id));
71 | }
72 |
73 | public static FileInputStream getStreamByName(String name) throws FileNotFoundException{
74 | return new FileInputStream(MAP_FOLDER + "/" + name);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/map/OfficialMap.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game.map;
11 |
12 | public class OfficialMap
13 | {
14 | public static String[] maps = {
15 | "[p2]Beach landing (2p) [by hxyy]",
16 | "[p2]Big Island (2p)",
17 | "[p2]Dire_Straight (2p) [by uber]",
18 | "[p2]Fire Bridge (2p) [by uber]",
19 | "[p2]Hills_(2p)_[By Tstis & KPSS]",
20 | "[p2]Ice Island (2p)",
21 | "[p2]Lake (2p)",
22 | "[p2]Small_Island (2p)",
23 | "[p2]Two_cold_sides (2p)",
24 | "[p3]Hercules_(2vs1p) [by_uber]",
25 | "[p3]King of the Middle (3p)",
26 | "[p4]Depth charges (4p) [by hxyy]",
27 | "[p4]Desert (4p)",
28 | "[p4]Ice Lake (4p) [by hxyy]",
29 | "[p4]Island freeze (4p) [by hxyy]",
30 | "[p4]Lava Maze (4p)",
31 | "[p4]Lava Vortex (4p)",
32 | "[p4]Nuclear war (4p) [by hxyy]",
33 | "[p4]Magma Island (4p)",
34 | "[p4]Islands (4p)",
35 | "[p6]Shore to Shore (6p)",
36 | "[p6]Valley Pass (6p)",
37 | "[p6]Crossing (6p)",
38 | "[p8]Bridges Over Lava (8p)",
39 | "[p8]Coastline (8p) [by hxyy]",
40 | "[p8]Huge Subdivide (8p)",
41 | "[p8]Interlocked (8p)",
42 | "[p8]Interlocked Large (8p)",
43 | "[p8]Isle Ring (8p)",
44 | "[p8]Large Ice Outcrop (8p)",
45 | "[p8]Lava Bio-grid(8p)",
46 | "[p8]Lava Divide(8p)",
47 | "[p8]Many Islands (8p)",
48 | "[p8]Random Islands (8p)",
49 | "[p8]Two Sides (8p)",
50 | "[p8]Volcano (8p)",
51 | "[p8]Volcano Crater(8p)",
52 | "[p8]Tornado eye (8p) [by hxyy]",
53 | "[z;p10]Enclosed Island (10p)",
54 | "[z;p10]Kingdoms (10p) [by Vulkan]",
55 | "[z;p10]Large Lava Divide (10p)",
56 | "[z;p10]Two Sides Remake (10p)",
57 | "[z;p10]Valley Arena (10p) [by_uber]",
58 | "[z;p10]Many Islands Large (10p)",
59 | "[z;p10]Crossing Large (10p)",
60 | "[z;p10]Enclosed Island (10p)",
61 | "[z;p10]Two_Large_Islands_(10p)",
62 | "[z;p10]Wetlands (10p)"};
63 |
64 | public static String[] mapsName = {
65 | "Beach landing (2p) [by hxyy]",
66 | "Big Island (2p)",
67 | "Dire Straight (2p) [by uber]",
68 | "Fire Bridge (2p) [by uber]",
69 | "Hills (2p) [By Tstis & KPSS]",
70 | "Ice Island (2p)",
71 | "Lake (2p)",
72 | "Small Island (2p)",
73 | "Two cold sides (2p)",
74 | "Hercules (2vs1p) [by uber]",
75 | "King of the Middle (3p)",
76 | "Depth charges (4p) [by hxyy]",
77 | "Desert (4p)",
78 | "Ice Lake (4p) [by hxyy]",
79 | "Island freeze (4p) [by hxyy]",
80 | "Lava Maze (4p)",
81 | "Lava Vortex (4p)",
82 | "Nuclear war (4p) [by hxyy]",
83 | "Magma Island (4p)",
84 | "Islands (4p)",
85 | "Shore to Shore (6p)",
86 | "Valley Pass (6p)",
87 | "Crossing (6p)",
88 | "Bridges Over Lava (8p)",
89 | "Coastline (8p) [by hxyy]",
90 | "Huge Subdivide (8p)",
91 | "Interlocked (8p)",
92 | "Interlocked Large (8p)",
93 | "Isle Ring (8p)",
94 | "Large Ice Outcrop (8p)",
95 | "Lava Bio-grid(8p)",
96 | "Lava Divide(8p)",
97 | "Many Islands (8p)",
98 | "Random Islands (8p)",
99 | "Two Sides (8p)",
100 | "Volcano (8p)",
101 | "Volcano Crater(8p)",
102 | "Tornado eye (8p) [by hxyy]",
103 | "Enclosed Island (10p)",
104 | "Kingdoms (10p) [by Vulkan]",
105 | "Large Lava Divide (10p)",
106 | "Two Sides Remake (10p)",
107 | "Valley Arena (10p) [by uber]",
108 | "Many Islands Large (10p)",
109 | "Crossing Large (10p)",
110 | "Enclosed Island (10p)",
111 | "Two Large Islands (10p)",
112 | "Wetlands (10p)"};
113 | }
114 |
115 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/mod/Mod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game.mod;
11 |
12 | import java.util.*;
13 |
14 | public class Mod
15 | {
16 | public static class ModUnit {
17 | private String modName;
18 | private String unitName;
19 | private int unitId;
20 |
21 | public ModUnit() {
22 | super();
23 | }
24 |
25 | public ModUnit(String unit, int id, String modname) {
26 | this.modName = modname;
27 | this.unitId = id;
28 | this.unitName = unit;
29 | }
30 |
31 | public void setModName(String modName)
32 | {
33 | this.modName = modName;
34 | }
35 |
36 | public String getModName()
37 | {
38 | return modName;
39 | }
40 |
41 | public void setUnitName(String unitName)
42 | {
43 | this.unitName = unitName;
44 | }
45 |
46 | public String getUnitName()
47 | {
48 | return unitName;
49 | }
50 |
51 | public void setUnitId(int unitId)
52 | {
53 | this.unitId = unitId;
54 | }
55 |
56 | public int getUnitId()
57 | {
58 | return unitId;
59 | }
60 | }
61 |
62 | private boolean isEnabled = true;
63 |
64 | private ArrayList unitList;
65 |
66 | public Mod(ArrayList list) {
67 | this.unitList = list;
68 | }
69 |
70 | public ArrayList getUnitList() {
71 | return unitList;
72 | };
73 |
74 | public void setEnabled(boolean bool) {
75 | this.isEnabled = bool;
76 | }
77 |
78 | public boolean isEnabled() {
79 | return isEnabled;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/mod/ModLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game.mod;
11 | import cn.rukkit.*;
12 | import com.alibaba.fastjson2.*;
13 | import java.io.*;
14 | import java.util.*;
15 | import org.slf4j.*;
16 |
17 | public class ModLoader
18 | {
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/mod/ModManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game.mod;
11 |
12 | import cn.rukkit.*;
13 | import cn.rukkit.game.mod.Mod.*;
14 | import com.alibaba.fastjson2.*;
15 | import java.io.*;
16 | import java.util.*;
17 | import org.slf4j.*;
18 |
19 | public class ModManager
20 | {
21 | private Logger log = LoggerFactory.getLogger(ModLoader.class);;
22 | private static String MOD_PATH = Rukkit.getEnvPath() + "/mods";
23 | private HashMap loadedMods = new HashMap();
24 | //private HashMap> loadedMods = new HashMap>();
25 |
26 | public ModManager () {
27 | if (!createModDir()) {
28 | log.error("ModManager::Mod Exception.Server will shutdown...");
29 | Rukkit.shutdown("Mod System fatal error.");
30 | }
31 | }
32 |
33 | private boolean createModDir() {
34 | File f = new File(MOD_PATH);
35 | if (f.exists() && f.isDirectory()) {
36 | return true;
37 | } else {
38 | //log.i("Mod folder is not exist.creating...");
39 | f.delete();
40 | f.mkdir();
41 | return true;
42 | }
43 | }
44 |
45 | public void loadAllModsInDir() {
46 | File dir = new File(MOD_PATH);
47 | log.info("" + dir);
48 | for (File f: dir.listFiles()) {
49 | if (f.getName().startsWith("mod_")) {
50 | String modname = f.getName().substring(4);
51 | try
52 | {
53 | loadMod(modname, f);
54 | }
55 | catch (IOException e)
56 | {
57 | log.error("Load Mod: " + modname + " failed.", e);
58 | //log.error(e);
59 | }
60 | }
61 | }
62 | }
63 |
64 | public Mod getModByString(String jsondata) {
65 | ArrayList li = new ArrayList();
66 | li = (ArrayList) JSON.parseArray(jsondata, ModUnit.class);
67 | return new Mod(li);
68 | }
69 |
70 | public void loadMod(String modname, File f) throws FileNotFoundException, IOException {
71 | log.info("Loading mod: " + modname);
72 | BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
73 | ArrayList li = new ArrayList();
74 | StringBuffer sbuf = new StringBuffer();
75 | String b = null;
76 | while ((b = reader.readLine()) != null)
77 | {
78 | sbuf.append(b);
79 | }
80 | li = (ArrayList) JSON.parseArray(sbuf.toString(), ModUnit.class);
81 | Mod mod = new Mod(li);
82 | //mod.setEnabled(true);
83 | loadedMods.put(modname, mod);
84 | }
85 |
86 | public void loadModInDir(String modname) throws IOException {
87 | loadMod(modname, new File(MOD_PATH + "/mod_" + modname + ".json"));
88 | }
89 |
90 | public void loadMod(String modname, Mod mod) {
91 | loadedMods.put(modname, mod);
92 | }
93 |
94 | public void enableMod(String modname) {
95 | try{
96 | loadedMods.getOrDefault(modname, null).setEnabled(true);
97 | } catch (NullPointerException e) {
98 | log.error(String.format("Mod '%s' is not exist.", modname), e);
99 | }
100 | }
101 |
102 | public void disableMod(String modname) {
103 | try{
104 | loadedMods.getOrDefault(modname, null).setEnabled(false);
105 | } catch (NullPointerException e) {
106 | log.error(String.format("Mod '%s' is not exist.", modname), e);
107 | }
108 | }
109 |
110 | public void disableAllMods() {
111 | for (Map.Entry mod: loadedMods.entrySet()) {
112 | ((Mod) mod.getValue()).setEnabled(false);
113 | }
114 | }
115 |
116 | public void enableAllMods() {
117 | for (Map.Entry mod: loadedMods.entrySet()) {
118 | ((Mod) mod.getValue()).setEnabled(true);
119 | }
120 | }
121 |
122 | public HashMap getLoadedModsMap() {
123 | return loadedMods;
124 | }
125 |
126 | public Mod fetchMod(String modname){
127 | return loadedMods.getOrDefault(modname, null);
128 | }
129 |
130 | public ArrayList fetchAllEnabledModUnits() {
131 | ArrayList list = new ArrayList();
132 | for (Map.Entry entry: loadedMods.entrySet()) {
133 | if (((Mod)entry.getValue()).isEnabled()) {
134 | list.addAll(((Mod)entry.getValue()).getUnitList());
135 | }
136 | }
137 | /*for(ModUnit u: list) {
138 | log.debug(String.format("Unit '%s' from '%s' (%d)", u.getModName(), u.getUnitName(), u.getUnitId()));
139 | }*/
140 | return list;
141 | }
142 |
143 | public void loadInternalMod() throws IOException {
144 | if (fetchMod("default") != null) {
145 | log.warn("Deafult mod already loaded.Ignoring...");
146 | return;
147 | }
148 | BufferedReader reader = new BufferedReader(new InputStreamReader(ModManager.this.getClass().getClassLoader().getResourceAsStream("mod_default.json")));
149 | ArrayList li = new ArrayList();
150 | StringBuffer sbuf = new StringBuffer();
151 | String b = null;
152 | while ((b = reader.readLine()) != null)
153 | {
154 | sbuf.append(b);
155 | }
156 | li = (ArrayList) JSON.parseArray(sbuf.toString(), Mod.ModUnit.class);
157 | /*for(ModUnit u: li) {
158 | log.d(u.getModName());
159 | }*/
160 | Mod mod = new Mod(li);
161 | mod.setEnabled(true);
162 | loadMod("default", mod);
163 | //return li;
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/game/unit/InternalUnit.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.game.unit;
11 |
12 | public class InternalUnit
13 | {
14 | public static final String units[] = {
15 | "extractor",
16 | "landFactory",
17 | "airFactory",
18 | "seaFactory",
19 | "commandCenter",
20 | "turret",
21 | "antiAirTurret",
22 | "builder",
23 | "tank",
24 | "hoverTank",
25 | "artillery",
26 | "helicopter",
27 | "airShip",
28 | "gunShip",
29 | "missileShip",
30 | "gunBoat",
31 | "megaTank",
32 | "laserTank",
33 | "hovercraft",
34 | "ladybug",
35 | "battleShip",
36 | "tankDestroyer",
37 | "heavyTank",
38 | "heavyHoverTank",
39 | "laserDefence",
40 | "dropship",
41 | "tree",
42 | "repairbay",
43 | "NukeLaucher",
44 | "AntiNukeLaucher",
45 | "mammothTank",
46 | "experimentalTank",
47 | "experimentalLandFactory",
48 | "crystalResource",
49 | "wall_v",
50 | "fabricator",
51 | "attackSubmarine",
52 | "builderShip",
53 | "amphibiousJet",
54 | "supplyDepot",
55 | "experimentalHoverTank",
56 | "turret_artillery",
57 | "turret_flamethrower",
58 | "fogRevealer",
59 | "spreadingFire",
60 | "antiAirTurretT2",
61 | "turretT2",
62 | "turretT3",
63 | "damagingBorder",
64 | "zoneMarker",
65 | "editorOrBuilder",
66 | "dummyNonUnitWithTeam"
67 | };
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/Connection.java.bak:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 | import cn.rukkit.game.*;
12 | import cn.rukkit.network.packet.*;
13 | import java.io.*;
14 | import java.util.*;
15 | import java.util.concurrent.*;
16 | import cn.rukkit.*;
17 | import cn.rukkit.util.*;
18 | import cn.rukkit.network.command.*;
19 |
20 | @Deprecated
21 | public class Connection {
22 | public NetworkPlayer player;
23 | public ConnectionHandler handler;
24 | public long pingTime;
25 | public int lastSyncTick = -1;
26 | private ScheduledFuture pingFuture;
27 | private ScheduledFuture teamFuture;
28 | public SaveData save;
29 | //public ChannelHandlerContext ctx;
30 |
31 | /**
32 | * Ping runnable.
33 | */
34 | public class PingTasker implements Runnable {
35 | @Override
36 | public void run() {
37 | // TODO: Implement this method
38 | try {
39 | GameOutputStream o = new GameOutputStream();
40 | o.writeLong(new Random().nextLong());
41 | o.writeByte(0);
42 | Packet p = o.createPacket(108);
43 | handler.ctx.writeAndFlush(p);
44 | pingTime = System.currentTimeMillis();
45 | } catch (IOException e) {
46 | stopPingTask();
47 | }
48 | }
49 | }
50 |
51 | /**
52 | * TeamTask Scheduler.
53 | */
54 | public class TeamTasker implements Runnable {
55 | @Override
56 | public void run() {
57 | // TODO: Implement this method
58 | try
59 | {
60 | updateTeamList();
61 | }
62 | catch (IOException e)
63 | {
64 | stopTeamTask();
65 | //log.e(e);
66 | //e.printStackTrace();
67 | //cancel();
68 | }
69 | }
70 | }
71 |
72 | public Connection(ConnectionHandler handler) {
73 | this.handler = handler;
74 | }
75 |
76 | public void startPingTask() {
77 | if (pingFuture != null) return;
78 | pingFuture = Rukkit.getThreadManager().schedule(new PingTasker(), 2000, 2000);
79 | }
80 |
81 | public void startTeamTask() {
82 | if (teamFuture != null) return;
83 | teamFuture = Rukkit.getThreadManager().schedule(new TeamTasker(), 1000, 1000);
84 | }
85 |
86 | public void stopPingTask() {
87 | if (pingFuture == null) return;
88 | Rukkit.getThreadManager().shutdownTask(pingFuture);
89 | pingFuture = null;
90 | }
91 |
92 | public void stopTeamTask() {
93 | if (teamFuture == null) return;
94 | Rukkit.getThreadManager().shutdownTask(teamFuture);
95 | teamFuture = null;
96 | }
97 |
98 | public void sendChat(String msg) {
99 | try {
100 | Rukkit.getConnectionManager().broadcast(Packet.chat(player.name, msg, player.playerIndex));
101 | } catch (IOException ignored) {}
102 | }
103 |
104 | public void sendServerMessage(String msg) {
105 | try {
106 | handler.ctx.writeAndFlush(Packet.chat("SERVER", msg, -1));
107 | } catch (IOException e) {}
108 | }
109 |
110 | public void sendMessage(String from, String msg, int team) {
111 | try {
112 | handler.ctx.writeAndFlush(Packet.chat(from, msg, team));
113 | } catch (IOException e) {}
114 | }
115 |
116 | public void sendGameCommand(GameCommand cmd) {
117 | // If game is paused, throw everything.
118 | if (Rukkit.getGameServer().isPaused()) {
119 | return;
120 | }
121 | if (Rukkit.getConfig().useCommandQuere) {
122 | Rukkit.getGameServer().addCommand(cmd);
123 | } else {
124 | try {
125 | Rukkit.getConnectionManager().broadcast(Packet.gameCommand(Rukkit.getGameServer().getTickTime(), cmd));
126 | } catch (IOException ignored) {}
127 | }
128 | }
129 |
130 | public void updateTeamList() throws IOException {
131 | updateTeamList(Rukkit.getGameServer().isGaming());
132 | }
133 |
134 | public void updateTeamList(boolean simpleMode) throws IOException {
135 | GameOutputStream o = new GameOutputStream();
136 | //log.d("Sending teamlist...");
137 | o.writeInt(player.playerIndex);
138 | // 1.14新增
139 | o.writeBoolean(simpleMode);
140 | o.writeInt(Rukkit.getConfig().maxPlayer); //maxPlayer
141 | //1.14启用Gzip压缩
142 | GzipEncoder enc = o.getEncodeStream("teams", true);
143 |
144 | for (int i =0;i < Rukkit.getConfig().maxPlayer;i++)
145 | {
146 | NetworkPlayer playerp = Rukkit.getConnectionManager().getPlayerManager().get(i);
147 |
148 | // No-stop mode changes:Add fake players
149 | if (Rukkit.getConfig().nonStopMode) {
150 | // Always true
151 | enc.stream.writeBoolean(true);
152 | } else {
153 | enc.stream.writeBoolean(!playerp.isEmpty);
154 | }
155 |
156 | // Ignore empty player
157 | if (playerp.isEmpty) {
158 | if (!Rukkit.getConfig().nonStopMode){
159 | continue;
160 | }
161 | }
162 |
163 | //1.14
164 | //enc.stream.writeByte(0);
165 | enc.stream.writeInt(255);
166 | playerp.writePlayer(enc.stream, simpleMode);
167 | }
168 | o.flushEncodeData(enc);
169 |
170 | o.writeInt(Rukkit.getRoundConfig().fogType);
171 | o.writeInt(GameUtils.getMoneyFormat(Rukkit.getRoundConfig().credits));
172 | o.writeBoolean(true);
173 | //ai
174 | o.writeInt(1);
175 | //
176 | o.writeByte(4);
177 | //maxUnit
178 | o.writeInt(250);
179 | o.writeInt(250);
180 |
181 | //初始单位
182 | o.writeInt(Rukkit.getRoundConfig().startingUnits);
183 | o.writeFloat(Rukkit.getRoundConfig().income);
184 | o.writeBoolean(Rukkit.getRoundConfig().disableNuke);
185 | o.writeBoolean(false);
186 | o.writeBoolean(false);
187 | o.writeBoolean(Rukkit.getRoundConfig().sharedControl);
188 |
189 | Packet p = o.createPacket(Packet.PACKET_TEAM_LIST);
190 |
191 | handler.ctx.writeAndFlush(p);
192 | }
193 |
194 | public void kick(String reason) {
195 | try {
196 | handler.ctx.writeAndFlush(Packet.kick(reason));
197 | } catch (IOException e) {}
198 | }
199 |
200 | public void pong() {
201 | player.ping = (int) (System.currentTimeMillis() - pingTime);
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/GameInputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 |
12 | import cn.rukkit.network.packet.*;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import java.io.*;
16 | import java.util.*;
17 |
18 | public class GameInputStream
19 | {
20 | public ByteArrayInputStream buffer;
21 | public DataInputStream CurrentStream;
22 | public DataInputStream stream;
23 | public LinkedList blockQuere = new LinkedList();
24 |
25 | public GameInputStream(Packet packet) {
26 | this.buffer = new ByteArrayInputStream(packet.bytes);
27 | this.stream = new DataInputStream(this.buffer);
28 | this.CurrentStream = new DataInputStream(this.buffer);
29 | }
30 |
31 | public GameInputStream(byte[] b){
32 | this.buffer = new ByteArrayInputStream(b);
33 | this.stream = new DataInputStream(this.buffer);
34 | this.CurrentStream = new DataInputStream(this.buffer);
35 | }
36 |
37 | public GameInputStream(DataInputStream stream){
38 | //this.buffer = new ByteArrayInputStream(b);
39 | this.stream = stream;
40 | }
41 |
42 | public DataInputStream getUnDecodeStream() throws IOException
43 | {
44 | String blockName = this.readString();
45 | // LoggerFactory.getLogger("GameInputStream").info("BlockName: {}", blockName);
46 | byte[] bytes = readStreamBytes();
47 | return new DataInputStream(new ByteArrayInputStream(bytes));
48 | // TODO: Implement this method
49 | //return null;
50 | }
51 |
52 | public short readShort() throws IOException {
53 | return this.stream.readShort();
54 | }
55 |
56 | public byte readByte() throws IOException {
57 | return this.stream.readByte();
58 | }
59 |
60 | public boolean readBoolean() throws IOException {
61 | return this.stream.readBoolean();
62 | }
63 |
64 | public int readInt() throws IOException {
65 | return this.stream.readInt();
66 | }
67 |
68 | public float readFloat() throws IOException {
69 | return this.stream.readFloat();
70 | }
71 |
72 | public long readLong() throws IOException {
73 | return this.stream.readLong();
74 | }
75 |
76 | public String readString() throws IOException {
77 | return this.stream.readUTF();
78 | }
79 |
80 | public byte[] readStreamBytes() throws IOException {
81 | int n2;
82 | int n3 = this.readInt();
83 | byte[] arrby = new byte[n3];
84 | for (int i2 = 0; i2 < n3 && (n2 = this.stream.read(arrby, i2, n3 - i2)) != -1; i2 += n2) {
85 | }
86 | return arrby;
87 | }
88 |
89 | public DataInputStream getDecodeStream() throws IOException{
90 | String blockName = this.readString();
91 | // LoggerFactory.getLogger("GameInputStream").info("BlockName: {}", blockName);
92 | byte[] bytes = readStreamBytes();
93 | GzipDecoder coder = new GzipDecoder(bytes);
94 | return coder.stream;
95 | }
96 |
97 | /*
98 | * get decoded bytes.
99 | *
100 | */
101 | public byte[] getDecodeBytes() throws IOException{
102 | this.readString();
103 | byte[] bytes = readStreamBytes();
104 | return bytes;
105 | }
106 |
107 | public Enum readEnum(Class clazz) throws IOException{
108 | int i = this.readInt();
109 | return (Enum)clazz.getEnumConstants()[i];
110 | }
111 |
112 | public boolean readMark() throws IOException {
113 | short mark = this.readShort();
114 | if (mark != 12345) {
115 | LoggerFactory.getLogger("GameInputStream").error("Failed to readMark: {} != 12345", mark);
116 | return false;
117 | } else {
118 | return true;
119 | }
120 | }
121 |
122 | /*
123 | * Starts a block to read content.
124 | * Block content will buffered to List;
125 | */
126 | public void startBlock(boolean isCompressed) throws IOException {
127 | if (isCompressed) {
128 | stream = getDecodeStream();
129 | blockQuere.add(stream);
130 | } else {
131 | stream = getUnDecodeStream();
132 | blockQuere.add(stream);
133 | }
134 | }
135 |
136 | /*
137 | * Ends a block content.
138 | * Delete the buffer to get the current stream.
139 | */
140 | public void endBlock() {
141 | blockQuere.removeLast();
142 | if (blockQuere.size() == 0) {
143 | stream = CurrentStream;
144 | } else {
145 | stream = blockQuere.getLast();
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/GameOutputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 |
12 | import cn.rukkit.network.packet.*;
13 | import java.io.*;
14 | import java.util.*;
15 | import java.util.zip.*;
16 |
17 | public class GameOutputStream
18 | {
19 | public ByteArrayOutputStream buffer = new ByteArrayOutputStream();
20 | public DataOutputStream stream = new DataOutputStream(buffer);
21 | public DataOutputStream currentStream = new DataOutputStream(buffer);
22 | public LinkedList blockQuere = new LinkedList();
23 |
24 | private GZIPOutputStream gzipStream;
25 |
26 | private BufferedOutputStream bufferedStream;
27 |
28 | private ByteArrayOutputStream buff = new ByteArrayOutputStream();
29 |
30 | public Packet createPacket(int type) {
31 | try {
32 | while (blockQuere.size() != 0) {
33 | endBlock();
34 | }
35 | this.stream.flush();
36 | this.buffer.flush();
37 | Packet packet = new Packet(type);
38 | packet.bytes = this.buffer.toByteArray();
39 | return packet;
40 | } catch (IOException e) {
41 | throw new RuntimeException(e);
42 | }
43 | }
44 |
45 | public void writeByte(int val) throws IOException {
46 | this.stream.writeByte(val);
47 | }
48 |
49 | public void writeBoolean(boolean val) throws IOException {
50 | this.stream.writeBoolean(val);
51 | }
52 |
53 | public void writeInt(int val) throws IOException {
54 | this.stream.writeInt(val);
55 | }
56 |
57 | public void writeFloat(float val) throws IOException {
58 | this.stream.writeFloat(val);
59 | }
60 |
61 | public void writeLong(long val) throws IOException {
62 | this.stream.writeLong(val);
63 | }
64 |
65 | public void writeShort(short val) throws IOException {
66 | this.stream.writeShort(val);
67 | }
68 |
69 | public void writeString(String val) throws IOException {
70 | this.stream.writeUTF(val);
71 | }
72 |
73 | public void write(byte[] val) throws IOException {
74 | this.stream.write(val);
75 | this.stream.flush();
76 | }
77 |
78 | public GzipEncoder getEncodeStream(String key, boolean isGzip) throws IOException{
79 | GzipEncoder enc = new GzipEncoder(isGzip);
80 | enc.str = key;
81 | return enc;
82 | }
83 |
84 | public void writeFile(FileInputStream stream) throws IOException{
85 | byte[] filearr = new byte[stream.available()];
86 | int bytesRead = 0;
87 | while (bytesRead < filearr.length)
88 | {
89 | int readIn = stream.read(filearr, bytesRead, filearr.length - bytesRead);
90 | if (readIn == -1)
91 | {
92 | break;
93 | }
94 | bytesRead += readIn;
95 | }
96 | this.stream.writeInt(filearr.length);
97 | this.stream.write(filearr);
98 | }
99 |
100 | public void flushEncodeData(GzipEncoder enc) throws IOException{
101 | enc.flush();
102 | this.writeString(enc.str);
103 | this.writeInt(enc.buffer.size());
104 | enc.buffer.writeTo((OutputStream)this.stream);
105 | //stream.flush();
106 | }
107 |
108 | public void writeEnum(Enum clazz) throws IOException {
109 | this.writeInt(clazz.ordinal());
110 | //return (Enum)clazz.getEnumConstants()[i];
111 | }
112 |
113 | /*
114 | * Start to writing a content block.
115 | * @params blockName a block content name
116 | */
117 | public void startBlock(String blockName, boolean isGzip) throws IOException {
118 | GzipEncoder enc = getEncodeStream(blockName, isGzip);
119 | currentStream = stream;
120 | stream = enc.stream;
121 | blockQuere.addLast(enc);
122 | OutputStream outputStream;
123 | if (isGzip) {
124 | this.gzipStream = new GZIPOutputStream(this.buff);
125 | this.bufferedStream = new BufferedOutputStream(this.gzipStream);
126 | outputStream = this.bufferedStream;
127 | } else {
128 | outputStream = this.buff;
129 | }
130 | stream = new DataOutputStream(outputStream);
131 | }
132 |
133 | /*
134 | * End a content block.
135 | */
136 | public void endBlock() throws IOException {
137 | if (blockQuere.size() != 0) {
138 | GzipEncoder enc = blockQuere.removeLast();
139 | //enc.stream = stream;
140 | //enc.stream.write(stream.
141 | currentStream.writeUTF(enc.str);
142 | currentStream.writeInt(stream.size());
143 | buff.writeTo((OutputStream)this.currentStream);
144 | buff.flush();
145 | //detect next block
146 | if (blockQuere.size() == 0) {
147 | stream = currentStream;
148 | } else {
149 | stream = blockQuere.getLast().stream;
150 | }
151 | }
152 |
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/GlobalConnectionManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 | import io.netty.channel.group.*;
12 | import io.netty.util.concurrent.*;
13 |
14 | import java.io.IOException;
15 | import java.util.*;
16 | import cn.rukkit.game.*;
17 | import cn.rukkit.network.packet.*;
18 | import cn.rukkit.*;
19 | import org.slf4j.LoggerFactory;
20 | import org.slf4j.Logger;
21 |
22 | public class GlobalConnectionManager
23 | {
24 | List connections = new ArrayList();
25 | private static final ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup("ChannelGroups", GlobalEventExecutor.INSTANCE);
26 |
27 | //private PlayerManager playerManager;
28 |
29 | private RoomGameServer server;
30 |
31 | private Logger log = LoggerFactory.getLogger(GlobalConnectionManager.class);
32 |
33 | /**
34 | * Add a connection to list.
35 | * When player registered,this function will add it into management.
36 | */
37 | public void add(RoomConnection connection)
38 | {
39 | connections.add(connection);
40 | //playerManager.addWithTeam(connection.player);
41 | CHANNEL_GROUP.add(connection.handler.ctx.channel());
42 | }
43 |
44 | // @Deprecated
45 | // public void set(RoomConnection connection, int index) {
46 | // connections.add(connection);
47 | // //playerManager.set(index, connection.player);
48 | // CHANNEL_GROUP.add(connection.handler.ctx.channel());
49 | // }
50 |
51 | /**
52 | * Broadcast a message to all connections.
53 | * @params msg Packet msg.
54 | */
55 | public ChannelGroupFuture broadcast(Packet msg)
56 | {
57 | return CHANNEL_GROUP.writeAndFlush(msg);
58 | }
59 |
60 | /**
61 | * Broadcast a message to all connections,but using a ChannelMatcher.
62 | * @params msg Packet msg.
63 | * @params matcher ChannelMatcher.
64 | */
65 | public ChannelGroupFuture broadcast(Packet msg, ChannelMatcher matcher)
66 | {
67 | return CHANNEL_GROUP.writeAndFlush(msg, matcher);
68 | }
69 |
70 | /**
71 | * Flush all connections.
72 | */
73 | public ChannelGroup flush()
74 | {
75 | return CHANNEL_GROUP.flush();
76 | }
77 |
78 | /**
79 | * Discard a connection.Auto disconnect when connection discorded.
80 | * @params connection Connection to discard.
81 | */
82 | public boolean discard(RoomConnection connection)
83 | {
84 | connection.handler.ctx.disconnect();
85 | connections.remove(connection);
86 | //playerManager.remove(connection.player);
87 | // Check privs.
88 | // if (connection.player.isAdmin && Rukkit.getConnectionManager().getPlayerManager().getPlayerCount() > 0) {
89 | // for (NetworkPlayer p : playerManager.getPlayerArray()) {
90 | // if (!p.isEmpty) {
91 | // p.isAdmin = true;
92 | // break;
93 | // }
94 | // }
95 | // }
96 | return CHANNEL_GROUP.remove(connection.handler.ctx.channel());
97 | }
98 |
99 | /**
100 | * Disconnect all Connections.
101 | */
102 | public ChannelGroupFuture disconnect()
103 | {
104 | return CHANNEL_GROUP.disconnect();
105 | }
106 |
107 | /**
108 | * Disconnect Connections with ChannelMatcher.
109 | * @params matcher ChannelMatcher
110 | */
111 | public ChannelGroupFuture disconnect(ChannelMatcher matcher)
112 | {
113 | return CHANNEL_GROUP.disconnect(matcher);
114 | }
115 |
116 | /**
117 | * check a connection whether in Group.
118 | * @params connection Connection need to be checked.
119 | */
120 | public boolean contains(RoomConnection connection)
121 | {
122 | return CHANNEL_GROUP.contains(connection.handler.ctx.channel());
123 | }
124 |
125 | /**
126 | * Return Group size.
127 | */
128 | public int size()
129 | {
130 | return CHANNEL_GROUP.size();
131 | }
132 |
133 | /**
134 | * Init a ConnectionManager.
135 | * @params server GameServer
136 | */
137 | public GlobalConnectionManager(RoomGameServer server) {
138 | this.server = server;
139 | //playerManager = new PlayerManager(Rukkit.getConfig().maxPlayer);
140 | }
141 |
142 | /**
143 | * 根据名称获取玩家对象
144 | * @param name
145 | * @return
146 | */
147 | public NetworkPlayer getPlayerByName(String name) {
148 | for (RoomConnection conn: connections) {
149 | if (conn.player.name.equals(name)) {
150 | return conn.player;
151 | }
152 | }
153 | return null;
154 | }
155 |
156 | /**
157 | * 根据UUID获取玩家对象(推荐使用,更加可靠)
158 | * @param UUID
159 | * @return
160 | */
161 | public NetworkPlayer getPlayerByUUID(String UUID) {
162 | for (RoomConnection conn: connections) {
163 | if (conn.player.uuid.equals(UUID)) {
164 | return conn.player;
165 | }
166 | }
167 | return null;
168 | }
169 |
170 | /**
171 | * 根据UUID获取玩家对象(包括可断线重连的玩家)
172 | * 效率较低谨慎使用!
173 | * @param UUID
174 | * @return
175 | */
176 | public NetworkPlayer getAllPlayerByUUID(String UUID) {
177 | for (NetworkRoom room: Rukkit.getRoomManager().roomList) {
178 | NetworkPlayer player;
179 | if ((player = room.playerManager.getPlayerByUUID(UUID)) != null) {
180 | return player;
181 | }
182 | }
183 | return null;
184 | }
185 |
186 | /**
187 | * Get playerManager.
188 | */
189 | // public PlayerManager getGlobalPlayerManager() {
190 | // return playerManager;
191 | // }
192 |
193 | /**
194 | * Get connections
195 | */
196 | public List getConnections() {
197 | return connections;
198 | }
199 |
200 | // @Deprecated
201 | // public void registerPlayer(Connection connection) {
202 | //
203 | // }
204 |
205 | // @Deprecated
206 | // public SaveData getAvailableSave() {
207 | // for (Connection conn : connections) {
208 | // if (conn.save != null) {
209 | // log.debug("Get client save, tick={}, server tick={}", conn.save.time, Rukkit.getGameServer().getTickTime());
210 | // if (Math.abs(conn.save.time - server.getTickTime()) < Integer.MAX_VALUE) {
211 | // return conn.save;
212 | // }
213 | // }
214 | // }
215 | // return null;
216 | // }
217 | //
218 | // @Deprecated
219 | // public void clearAllSaveData() {
220 | // for (Connection conn : connections) {
221 | // conn.save = null;
222 | // }
223 | // }
224 |
225 | // @Deprecated
226 | // public void broadcastServerMessage(String msg) {
227 | // try {
228 | // broadcast(Packet.chat("SERVER", msg, -1));
229 | // } catch (IOException ignored) {}
230 | // }
231 |
232 | public void broadcastGlobalServerMessage(String msg) {
233 | try {
234 | broadcast(Packet.chat("SERVER", msg, -1));
235 | } catch (IOException ignored) {}
236 | }
237 |
238 | /**
239 | * Broadcast server info.(No admin trigger.)
240 | */
241 | // @Deprecated
242 | // public void broadcastServerInfo() {
243 | // try {
244 | // broadcast(Packet.serverInfo(false));
245 | // } catch (IOException ignored) {}
246 | // }
247 |
248 | }
249 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/GzipDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 |
12 | import java.io.*;
13 | import java.util.zip.*;
14 |
15 | public class GzipDecoder
16 | {
17 | public ByteArrayInputStream buffer;
18 | public DataInputStream stream;
19 |
20 | public GzipDecoder(byte[] bytes) throws IOException {
21 | this.buffer = new ByteArrayInputStream(bytes);
22 | BufferedInputStream in = new BufferedInputStream((InputStream)new GZIPInputStream((InputStream)this.buffer));
23 | this.stream = new DataInputStream((InputStream)in);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/GzipEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 |
12 | import java.io.*;
13 | import java.util.zip.*;
14 |
15 | public class GzipEncoder
16 | {
17 | /* renamed from: a */
18 | public GZIPOutputStream gzipStream;
19 |
20 | public String str;
21 |
22 | /* renamed from: b */
23 | public BufferedOutputStream bufferedStream;
24 |
25 | /* renamed from: c */
26 | public String f4919c;
27 |
28 | /* renamed from: d */
29 | public ByteArrayOutputStream buffer = new ByteArrayOutputStream();
30 |
31 | /* renamed from: e */
32 | public DataOutputStream stream;
33 |
34 | /* renamed from: f */
35 | public boolean f4922f = false;
36 |
37 | /* renamed from: a */
38 | public final void flush() throws IOException {
39 | this.buffer.flush();
40 | if (this.bufferedStream != null) {
41 | this.bufferedStream.flush();
42 | }
43 | if (this.gzipStream != null) {
44 | this.gzipStream.finish();
45 | }
46 | }
47 |
48 | public GzipEncoder(boolean z) throws IOException {
49 | OutputStream outputStream;
50 | if (z) {
51 | this.gzipStream = new GZIPOutputStream(this.buffer);
52 | this.bufferedStream = new BufferedOutputStream(this.gzipStream);
53 | outputStream = this.bufferedStream;
54 | } else {
55 | outputStream = this.buffer;
56 | }
57 | this.stream = new DataOutputStream(outputStream);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/RoomConnection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 |
12 | import cn.rukkit.Rukkit;
13 | import cn.rukkit.game.NetworkPlayer;
14 | import cn.rukkit.game.SaveData;
15 | import cn.rukkit.network.command.GameCommand;
16 | import cn.rukkit.network.packet.Packet;
17 | import cn.rukkit.util.GameUtils;
18 |
19 | import java.io.IOError;
20 | import java.io.IOException;
21 | import java.util.Random;
22 | import java.util.concurrent.ScheduledFuture;
23 |
24 | public class RoomConnection {
25 | public NetworkPlayer player;
26 | public ConnectionHandler handler;
27 | public NetworkRoom currectRoom;
28 | public long pingTime;
29 | public int lastSyncTick = 0;
30 | public boolean checkSumSent = false;
31 | public int numberOfDesyncError = 0;
32 |
33 | private ScheduledFuture pingFuture;
34 | private ScheduledFuture teamFuture;
35 | public SaveData save;
36 | //public ChannelHandlerContext ctx;
37 |
38 | /**
39 | * 心跳包任务
40 | * Ping runnable.
41 | */
42 | public class PingTasker implements Runnable {
43 | @Override
44 | public void run() {
45 | // TODO: Implement this method
46 | try {
47 | GameOutputStream o = new GameOutputStream();
48 | o.writeLong(new Random().nextLong());
49 | o.writeByte(0);
50 | Packet p = o.createPacket(108);
51 | handler.ctx.writeAndFlush(p);
52 | pingTime = System.currentTimeMillis();
53 | } catch (IOException e) {
54 | stopPingTask();
55 | }
56 | }
57 | }
58 |
59 | /**
60 | * 队伍列表任务
61 | * TeamTask Scheduler.
62 | */
63 | public class TeamTasker implements Runnable {
64 | @Override
65 | public void run() {
66 | // TODO: Implement this method
67 | try
68 | {
69 | updateTeamList();
70 | }
71 | catch (IOException e)
72 | {
73 | stopTeamTask();
74 | //log.e(e);
75 | //e.printStackTrace();
76 | //cancel();
77 | }
78 | }
79 | }
80 |
81 | public RoomConnection(ConnectionHandler handler, NetworkRoom currectRoom) {
82 | this.handler = handler;
83 | this.currectRoom = currectRoom;
84 | }
85 |
86 | public void startPingTask() {
87 | if (pingFuture != null) return;
88 | pingFuture = Rukkit.getThreadManager().schedule(new PingTasker(), 2000, 2000);
89 | }
90 |
91 | public void startTeamTask() {
92 | if (teamFuture != null) return;
93 | teamFuture = Rukkit.getThreadManager().schedule(new TeamTasker(), 1000, 1000);
94 | }
95 |
96 | public void stopPingTask() {
97 | if (pingFuture == null) return;
98 | Rukkit.getThreadManager().shutdownTask(pingFuture);
99 | pingFuture = null;
100 | }
101 |
102 | public void stopTeamTask() {
103 | if (teamFuture == null) return;
104 | Rukkit.getThreadManager().shutdownTask(teamFuture);
105 | teamFuture = null;
106 | }
107 |
108 | public void doChecksum() {
109 | try {
110 | handler.ctx.writeAndFlush(Packet.syncCheckSum(lastSyncTick));
111 | } catch (IOException ignored) {}
112 | }
113 |
114 | /**
115 | * 发送公开聊天
116 | * @param msg
117 | */
118 | public void sendChat(String msg) {
119 | try {
120 | currectRoom.connectionManager.broadcast(Packet.chat(player.name, msg, player.playerIndex));
121 | } catch (IOException ignored) {}
122 | }
123 |
124 | /**
125 | * 发送服务器信息 ([SERVER])
126 | * @param msg
127 | */
128 | public void sendServerMessage(String msg) {
129 | try {
130 | handler.ctx.writeAndFlush(Packet.chat("SERVER", msg, -1));
131 | } catch (IOException e) {}
132 | }
133 |
134 | /**
135 | * 发送玩家信息
136 | * @param from 来源玩家名
137 | * @param msg 信息
138 | * @param team 队伍
139 | */
140 | public void sendMessage(String from, String msg, int team) {
141 | try {
142 | handler.ctx.writeAndFlush(Packet.chat(from, msg, team));
143 | } catch (IOException e) {}
144 | }
145 |
146 | /**
147 | * 发送游戏指令
148 | * @param cmd GameCommand实例.
149 | */
150 | public void sendGameCommand(GameCommand cmd) {
151 | // If game is paused, throw everything.
152 | if (currectRoom.isPaused()) {
153 | return;
154 | }
155 | if (Rukkit.getConfig().useCommandQuere) {
156 | currectRoom.addCommand(cmd);
157 | } else {
158 | try {
159 | currectRoom.connectionManager.broadcast(Packet.gameCommand(currectRoom.getTickTime(), cmd));
160 | } catch (IOException ignored) {}
161 | }
162 | }
163 |
164 | public void updateTeamList() throws IOException {
165 | updateTeamList(currectRoom.isGaming());
166 | }
167 |
168 | /**
169 | * 更新队伍列表。
170 | * @param simpleMode 简单模式(1.14+).减少网络数据通信。
171 | * @throws IOException
172 | */
173 | public void updateTeamList(boolean simpleMode) throws IOException {
174 | GameOutputStream o = new GameOutputStream();
175 | //log.d("Sending teamlist...");
176 | o.writeInt(player.playerIndex);
177 | // 1.14新增
178 | o.writeBoolean(simpleMode);
179 | o.writeInt(Rukkit.getConfig().maxPlayer); //maxPlayer
180 | //1.14启用Gzip压缩
181 | GzipEncoder enc = o.getEncodeStream("teams", true);
182 |
183 | for (int i =0;i < Rukkit.getConfig().maxPlayer;i++)
184 | {
185 | NetworkPlayer playerp = currectRoom.playerManager.get(i);
186 |
187 | enc.stream.writeBoolean(!playerp.isEmpty);
188 |
189 | // Ignore empty player
190 | if (playerp.isEmpty) {
191 | continue;
192 | }
193 |
194 | //1.14
195 | //enc.stream.writeByte(0);
196 |
197 | enc.stream.writeInt(255);
198 | playerp.writePlayer(enc.stream, simpleMode);
199 | }
200 | o.flushEncodeData(enc);
201 |
202 | o.writeInt(currectRoom.config.fogType);
203 | o.writeInt(GameUtils.getMoneyFormat(currectRoom.config.credits));
204 | o.writeBoolean(true);
205 | //ai
206 | o.writeInt(1);
207 | //
208 | o.writeByte(4);
209 | //maxUnit
210 | o.writeInt(250);
211 | o.writeInt(250);
212 |
213 | //初始单位
214 | o.writeInt(currectRoom.config.startingUnits);
215 | o.writeFloat(currectRoom.config.income);
216 | o.writeBoolean(currectRoom.config.disableNuke);
217 | o.writeBoolean(false);
218 | o.writeBoolean(false);
219 | o.writeBoolean(currectRoom.config.sharedControl);
220 |
221 | Packet p = o.createPacket(Packet.PACKET_TEAM_LIST);
222 |
223 | handler.ctx.writeAndFlush(p);
224 | }
225 |
226 | /**
227 | * 踢出玩家
228 | * @param reason 踢出理由
229 | */
230 | public void kick(String reason) {
231 | try {
232 | handler.ctx.writeAndFlush(Packet.kick(reason));
233 | } catch (IOException e) {}
234 | }
235 |
236 | /**
237 | * 心跳包返回
238 | */
239 | public void pong() {
240 | player.ping = (int) (System.currentTimeMillis() - pingTime);
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/RoomConnectionManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 |
12 | import cn.rukkit.Rukkit;
13 | import cn.rukkit.game.NetworkPlayer;
14 | import cn.rukkit.game.PlayerManager;
15 | import cn.rukkit.game.SaveData;
16 | import cn.rukkit.network.packet.Packet;
17 | import io.netty.channel.group.ChannelGroup;
18 | import io.netty.channel.group.ChannelGroupFuture;
19 | import io.netty.channel.group.ChannelMatcher;
20 | import io.netty.channel.group.DefaultChannelGroup;
21 | import io.netty.util.concurrent.GlobalEventExecutor;
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 |
25 | import java.io.IOException;
26 | import java.util.ArrayList;
27 | import java.util.List;
28 |
29 | public class RoomConnectionManager {
30 | private final NetworkRoom room;
31 | volatile List connections = new ArrayList();
32 | private ChannelGroup CHANNEL_GROUP;
33 |
34 | private PlayerManager playerManager;
35 |
36 | private RoomGameServer server;
37 |
38 | private Logger log;
39 |
40 | /**
41 | * Add a connection to list.
42 | * When player registered,this function will add it into management.
43 | */
44 | public void add(RoomConnection connection) {
45 | connections.add(connection);
46 | playerManager.addWithTeam(connection.player);
47 | CHANNEL_GROUP.add(connection.handler.ctx.channel());
48 | }
49 |
50 | public void set(RoomConnection connection, int index) {
51 | connections.add(connection);
52 | playerManager.set(index, connection.player);
53 | CHANNEL_GROUP.add(connection.handler.ctx.channel());
54 | }
55 |
56 | /**
57 | * Broadcast a message to all connections.
58 | *
59 | * @params msg Packet msg.
60 | */
61 | public ChannelGroupFuture broadcast(Packet msg) {
62 | return CHANNEL_GROUP.writeAndFlush(msg);
63 | }
64 |
65 | /**
66 | * Broadcast a message to all connections,but using a ChannelMatcher.
67 | *
68 | * @params msg Packet msg.
69 | * @params matcher ChannelMatcher.
70 | */
71 | public ChannelGroupFuture broadcast(Packet msg, ChannelMatcher matcher) {
72 | return CHANNEL_GROUP.writeAndFlush(msg, matcher);
73 | }
74 |
75 | /**
76 | * Flush all connections.
77 | */
78 | public ChannelGroup flush() {
79 | return CHANNEL_GROUP.flush();
80 | }
81 |
82 | /**
83 | * Discard a connection.Auto disconnect when connection discorded.
84 | *
85 | * @params connection Connection to discard.
86 | */
87 | public boolean discard(RoomConnection connection) {
88 | connection.handler.ctx.disconnect();
89 | connections.remove(connection);
90 | playerManager.remove(connection.player);
91 | // Check privs.
92 | if (connection.player.isAdmin && playerManager.getPlayerCount() > 0) {
93 | for (NetworkPlayer p : playerManager.getPlayerArray()) {
94 | if (!p.isEmpty) {
95 | p.isAdmin = true;
96 | try {
97 | p.getConnection().handler.ctx.writeAndFlush(Packet.serverInfo(room.config, true));
98 | } catch (IOException ignored) {}
99 | break;
100 | }
101 | }
102 | }
103 | return CHANNEL_GROUP.remove(connection.handler.ctx.channel());
104 | }
105 |
106 | /**
107 | * Disconnect all Connections.
108 | */
109 | public ChannelGroupFuture disconnect() {
110 | return CHANNEL_GROUP.disconnect();
111 | }
112 |
113 | /**
114 | * Disconnect Connections with ChannelMatcher.
115 | *
116 | * @params matcher ChannelMatcher
117 | */
118 | public ChannelGroupFuture disconnect(ChannelMatcher matcher) {
119 | return CHANNEL_GROUP.disconnect(matcher);
120 | }
121 |
122 | /**
123 | * check a connection whether in Group.
124 | *
125 | * @params connection need to be checked.
126 | */
127 | public boolean contains(RoomConnection connection) {
128 | return CHANNEL_GROUP.contains(connection.handler.ctx.channel());
129 | }
130 |
131 | /**
132 | * Return Group size.
133 | */
134 | public int size() {
135 | return CHANNEL_GROUP.size();
136 | }
137 |
138 | /**
139 | * Init a ConnectionManager.
140 | *
141 | * @params server GameServer
142 | */
143 | public RoomConnectionManager(NetworkRoom room) {
144 | this.room = room;
145 | playerManager = room.playerManager;
146 | log = LoggerFactory.getLogger("RoomConnectionManager #" + room.roomId);
147 | CHANNEL_GROUP = new DefaultChannelGroup("ChannelGroups" + room.roomId, GlobalEventExecutor.INSTANCE);
148 | }
149 |
150 | public void getPlayerAsList() {
151 |
152 | }
153 |
154 | /**
155 | * Get connections
156 | */
157 | public List getConnections() {
158 | return connections;
159 | }
160 |
161 | // public void registerPlayer(Connection connection) {
162 | //
163 | // }
164 |
165 | public SaveData getAvailableSave() {
166 | for (RoomConnection conn : connections) {
167 | if (conn.save != null) {
168 | log.debug("Get client save, tick={}, server tick={}", conn.save.time, room.getCurrentStep());
169 | if (Math.abs(conn.save.time - room.getCurrentStep()) < Integer.MAX_VALUE) {
170 | return conn.save;
171 | }
172 | }
173 | }
174 | return null;
175 | }
176 |
177 | public void clearAllSaveData() {
178 | for (RoomConnection conn : connections) {
179 | conn.save = null;
180 | }
181 | }
182 |
183 | public void broadcastServerMessage(String msg) {
184 | try {
185 | broadcast(Packet.chat("SERVER", msg, -1));
186 | } catch (IOException ignored) {
187 | }
188 | }
189 |
190 | public void broadcastGlobalServerMessage(String msg) {
191 | try {
192 | broadcast(Packet.chat("SERVER", msg, -1));
193 | } catch (IOException ignored) {
194 | }
195 | }
196 |
197 | /**
198 | * Broadcast server info.(No admin trigger.)
199 | */
200 | public void broadcastServerInfo() {
201 | try {
202 | broadcast(Packet.serverInfo(room.config, false));
203 | } catch (IOException ignored) {
204 | }
205 | }
206 |
207 | }
208 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/RoomGameServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network;
11 |
12 | import cn.rukkit.Rukkit;
13 | import cn.rukkit.network.packet.PacketDecoder;
14 | import cn.rukkit.network.packet.PacketEncoder;
15 | import io.netty.bootstrap.ServerBootstrap;
16 | import io.netty.channel.ChannelFuture;
17 | import io.netty.channel.ChannelInitializer;
18 | import io.netty.channel.ChannelOption;
19 | import io.netty.channel.nio.NioEventLoopGroup;
20 | import io.netty.channel.socket.SocketChannel;
21 | import io.netty.channel.socket.nio.NioServerSocketChannel;
22 | import io.netty.handler.logging.LogLevel;
23 | import io.netty.handler.logging.LoggingHandler;
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 |
27 | public class RoomGameServer {
28 | private NioEventLoopGroup bossGroup;
29 | private NioEventLoopGroup workerGroup;
30 | private ChannelFuture serverFuture;
31 |
32 | private Logger log = LoggerFactory.getLogger("GameServer");
33 |
34 | /**
35 | * Start a Server.
36 | */
37 | public void action(final long time) throws InterruptedException {
38 | // 用来接收进来的连接
39 | bossGroup = new NioEventLoopGroup();
40 | // 用来处理已经被接收的连接,一旦bossGroup接收到连接,就会把连接信息注册到workerGroup上
41 | workerGroup = new NioEventLoopGroup();
42 | try {
43 | ServerBootstrap sbs = new ServerBootstrap();
44 | sbs.group(bossGroup, workerGroup)
45 | .channel(NioServerSocketChannel.class)
46 | .option(ChannelOption.SO_BACKLOG, 128)
47 | .childOption(ChannelOption.SO_KEEPALIVE, true)
48 | //.handler(new LoggingHandler(log))
49 | .handler(new LoggingHandler(log.getName(), LogLevel.DEBUG))
50 | .childHandler(new ChannelInitializer(){
51 |
52 | @Override
53 | protected void initChannel(SocketChannel p1) throws Exception {
54 | // TODO: Implement this method
55 | p1.pipeline().addLast(new PacketDecoder());
56 | p1.pipeline().addLast(new PacketEncoder()).addLast(new ConnectionHandler());
57 | }
58 | });
59 | //System.out.println("-Server started!");
60 | new Thread(new Runnable() {
61 | @Override
62 | public void run() {
63 | log.info("Done! (" + (System.currentTimeMillis() - time) + "ms)");
64 | Rukkit.setStarted(true);
65 | // TODO: Implement this method
66 | }
67 | }).start();
68 | serverFuture = sbs.bind(Rukkit.getConfig().serverPort).sync();
69 | serverFuture.channel().closeFuture().sync();
70 | } catch (Exception e) {
71 | log.error("A error occurred: ", e);
72 | Rukkit.shutdown(e.getMessage());
73 | bossGroup.shutdownGracefully();
74 | workerGroup.shutdownGracefully();
75 | return;
76 | } finally {
77 | bossGroup.shutdownGracefully();
78 | workerGroup.shutdownGracefully();
79 | }
80 | }
81 |
82 | public void stopServer() {
83 | workerGroup.shutdownGracefully();
84 | bossGroup.shutdownGracefully();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/RoomManager.java:
--------------------------------------------------------------------------------
1 | package cn.rukkit.network;
2 |
3 | import cn.rukkit.Rukkit;
4 | import cn.rukkit.config.RoundConfig;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | public class RoomManager {
10 | public List roomList;
11 | public RoomManager(RoundConfig defaultConfig, int maxRoom) {
12 | roomList = new ArrayList(maxRoom);
13 | resetAllRooms();
14 | }
15 |
16 | public void addConnection(RoomConnection conn, int roomId) {
17 |
18 | }
19 |
20 | public void addConnection(RoomConnection conn) {
21 |
22 | }
23 |
24 | /**
25 | * 获取当前的默认房间(id = 0).
26 | * @return 房间实例
27 | */
28 | public NetworkRoom getDefaultRoom() {
29 | return roomList.get(0);
30 | }
31 |
32 | /**
33 | * 获取房间。根据房间id进入。
34 | * @param index
35 | * @return
36 | */
37 | public NetworkRoom getRoom(int index) {
38 | return roomList.get(index);
39 | }
40 |
41 | /**
42 | * 获得当前可用的房间。
43 | * @return NetworkRoom实例.
44 | */
45 | public NetworkRoom getAvailableRoom() {
46 | for (NetworkRoom room: roomList) {
47 | if (room.playerManager.getPlayerCount() < room.playerManager.getMaxPlayer()){
48 | if (!room.isGaming()) {
49 | return room;
50 | }
51 | }
52 | }
53 | return null;
54 | }
55 |
56 | /**
57 | * Reset all Rooms.
58 | * 重置所有房间。重置后房间数是rukkit.yml处的 maxRoom
59 | */
60 | public void resetAllRooms() {
61 | for (NetworkRoom room: roomList) {
62 | if (room != null) {
63 | room.connectionManager.broadcastServerMessage("Room reset.");
64 | room.connectionManager.disconnect();
65 | room.discard();
66 | roomList.remove(room);
67 | }
68 | }
69 | for (int id = 0;id < Rukkit.getConfig().maxRoom;id ++){
70 | roomList.add(new NetworkRoom(id));
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/cn/rukkit/network/packet/PacketDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2022 RukkitDev Team and contributors.
3 | *
4 | * This project uses GNU Affero General Public License v3.0.You can find this license in the following link.
5 | * 本项目使用 GNU Affero General Public License v3.0 许可证,你可以在下方链接查看:
6 | *
7 | * https://github.com/RukkitDev/Rukkit/blob/master/LICENSE
8 | */
9 |
10 | package cn.rukkit.network.packet;
11 |
12 | import io.netty.buffer.*;
13 | import io.netty.channel.*;
14 | import io.netty.handler.codec.*;
15 | import java.util.*;
16 | import org.slf4j.*;
17 |
18 | public class PacketDecoder extends ByteToMessageDecoder
19 | {
20 |
21 | private static final int HEAD_SIZE = 8;
22 | private static Logger log = LoggerFactory.getLogger(PacketDecoder.class);
23 |
24 | @Override
25 | protected void decode(ChannelHandlerContext p1, ByteBuf p2, List