mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
[FEATURE] RemoteControlModule
This commit is contained in:
parent
6127e92ce5
commit
afc84ebae8
7 changed files with 71 additions and 14 deletions
|
@ -1,4 +1,5 @@
|
||||||
# GravitLauncher GitConvention #
|
# GravitLauncher GitConvention #
|
||||||
|
|
||||||
Цель конвенции — внедрить простые, прозрачные и эффективные правила работы с Git.
|
Цель конвенции — внедрить простые, прозрачные и эффективные правила работы с Git.
|
||||||
|
|
||||||
Разработка GravitLauncher идёт на базе [Git Flow](https://leanpub.com/git-flow/read). Подробности ниже.
|
Разработка GravitLauncher идёт на базе [Git Flow](https://leanpub.com/git-flow/read). Подробности ниже.
|
||||||
|
@ -14,12 +15,15 @@
|
||||||
| **bugfix-*** | Исправляет баг нового функционала | **release** | *bugfix-auth* |
|
| **bugfix-*** | Исправляет баг нового функционала | **release** | *bugfix-auth* |
|
||||||
| **feature-*** | Добавляет новую возможность | **develop** | *feature-auth* |
|
| **feature-*** | Добавляет новую возможность | **develop** | *feature-auth* |
|
||||||
| **hotfix-*** | Вносит срочное исправление для production-а | **master** | *hotfix-auth* |
|
| **hotfix-*** | Вносит срочное исправление для production-а | **master** | *hotfix-auth* |
|
||||||
|
|
||||||
-----
|
-----
|
||||||
![Image of GitFlow](https://i.ytimg.com/vi/w2r0oLFtXAw/maxresdefault.jpg)
|
![Image of GitFlow](https://i.ytimg.com/vi/w2r0oLFtXAw/maxresdefault.jpg)
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## Коммиты ##
|
## Коммиты ##
|
||||||
|
|
||||||
**Основные правила:**
|
**Основные правила:**
|
||||||
|
|
||||||
1. Все коммиты должны быть на русском языке.
|
1. Все коммиты должны быть на русском языке.
|
||||||
2. Запрещено использовать прошедшее время.
|
2. Запрещено использовать прошедшее время.
|
||||||
3. Обязательно должен быть использован префикс.
|
3. Обязательно должен быть использован префикс.
|
||||||
|
@ -27,6 +31,7 @@
|
||||||
5. Длина любой части не должна превышать 100 символов.
|
5. Длина любой части не должна превышать 100 символов.
|
||||||
|
|
||||||
**Структура:**
|
**Структура:**
|
||||||
|
|
||||||
```
|
```
|
||||||
[Префикс] <Сообщение>
|
[Префикс] <Сообщение>
|
||||||
```
|
```
|
||||||
|
|
|
@ -11,6 +11,7 @@ public class PingServerManager {
|
||||||
public static final long REPORT_EXPIRED_TIME = 20 * 1000;
|
public static final long REPORT_EXPIRED_TIME = 20 * 1000;
|
||||||
public final Map<String, ServerInfoEntry> map = new HashMap<>();
|
public final Map<String, ServerInfoEntry> map = new HashMap<>();
|
||||||
private final LaunchServer server;
|
private final LaunchServer server;
|
||||||
|
|
||||||
public PingServerManager(LaunchServer server) {
|
public PingServerManager(LaunchServer server) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
package pro.gravit.launchserver.socket.handlers;
|
package pro.gravit.launchserver.socket.handlers;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||||
import io.netty.handler.codec.http.FullHttpRequest;
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
|
import io.netty.handler.codec.http.FullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launchserver.socket.NettyConnectContext;
|
import pro.gravit.launchserver.socket.NettyConnectContext;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
|
||||||
|
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||||
|
|
||||||
public class NettyWebAPIHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
public class NettyWebAPIHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
||||||
private static final TreeSet<SeverletPathPair> severletList = new TreeSet<>(Comparator.comparingInt((e) -> -e.key.length()));
|
private static final TreeSet<SeverletPathPair> severletList = new TreeSet<>(Comparator.comparingInt((e) -> -e.key.length()));
|
||||||
private final NettyConnectContext context;
|
private final NettyConnectContext context;
|
||||||
|
@ -38,7 +51,12 @@ protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) thro
|
||||||
boolean isNext = true;
|
boolean isNext = true;
|
||||||
for (SeverletPathPair pair : severletList) {
|
for (SeverletPathPair pair : severletList) {
|
||||||
if (msg.uri().startsWith(pair.key)) {
|
if (msg.uri().startsWith(pair.key)) {
|
||||||
|
try {
|
||||||
pair.callback.handle(ctx, msg, context);
|
pair.callback.handle(ctx, msg, context);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
ctx.writeAndFlush(new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR, Unpooled.wrappedBuffer("Internal Server Error 500".getBytes())), ctx.voidPromise());
|
||||||
|
}
|
||||||
isNext = false;
|
isNext = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +70,39 @@ protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) thro
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface SimpleSeverletHandler {
|
public interface SimpleSeverletHandler {
|
||||||
void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context) throws Exception;
|
void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context) throws Exception;
|
||||||
|
|
||||||
|
default Map<String, String> getParamsFromUri(String uri) {
|
||||||
|
int ind = uri.indexOf("?");
|
||||||
|
if (ind <= 0) {
|
||||||
|
return Map.of();
|
||||||
|
}
|
||||||
|
String sub = uri.substring(ind + 1);
|
||||||
|
String[] result = sub.split("&");
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
for (int i = 0; i < result.length; ++i) {
|
||||||
|
String c = URLDecoder.decode(result[i], Charset.defaultCharset());
|
||||||
|
int index = c.indexOf("=");
|
||||||
|
if (index <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String key = c.substring(0, index);
|
||||||
|
String value = c.substring(index);
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
default FullHttpResponse simpleResponse(HttpResponseStatus status, String body) {
|
||||||
|
return new DefaultFullHttpResponse(HTTP_1_1, status, body != null ? Unpooled.wrappedBuffer(body.getBytes()) : Unpooled.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
default FullHttpResponse simpleJsonResponse(HttpResponseStatus status, Object body) {
|
||||||
|
return new DefaultFullHttpResponse(HTTP_1_1, status, body != null ? Unpooled.wrappedBuffer(Launcher.gsonManager.gson.toJson(body).getBytes()) : Unpooled.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
default void sendHttpResponse(ChannelHandlerContext ctx, FullHttpResponse response) {
|
||||||
|
ctx.writeAndFlush(response, ctx.voidPromise());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SeverletPathPair {
|
public static class SeverletPathPair {
|
||||||
|
|
|
@ -26,6 +26,7 @@ public static class PingServerReport {
|
||||||
//Server addional info
|
//Server addional info
|
||||||
public double tps; //Server tps
|
public double tps; //Server tps
|
||||||
public List<UsernameInfo> users;
|
public List<UsernameInfo> users;
|
||||||
|
|
||||||
public PingServerReport(String name, int maxPlayers, int playersOnline) {
|
public PingServerReport(String name, int maxPlayers, int playersOnline) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.maxPlayers = maxPlayers;
|
this.maxPlayers = maxPlayers;
|
||||||
|
|
|
@ -55,7 +55,7 @@ public static String multiReplace(Pattern[] pattern, String from, String replace
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ScriptEngine newScriptEngine() {
|
public static ScriptEngine newScriptEngine() {
|
||||||
if(nashornFactory == null) {
|
if (nashornFactory == null) {
|
||||||
throw new UnsupportedOperationException("ScriptEngine not supported");
|
throw new UnsupportedOperationException("ScriptEngine not supported");
|
||||||
}
|
}
|
||||||
return nashornFactory.getScriptEngine();
|
return nashornFactory.getScriptEngine();
|
||||||
|
|
|
@ -81,9 +81,8 @@ public boolean auth() {
|
||||||
for (ClientProfile p : result.profiles) {
|
for (ClientProfile p : result.profiles) {
|
||||||
LogHelper.debug("Get profile: %s", p.getTitle());
|
LogHelper.debug("Get profile: %s", p.getTitle());
|
||||||
boolean isFound = false;
|
boolean isFound = false;
|
||||||
for(ClientProfile.ServerProfile srv : p.getServers())
|
for (ClientProfile.ServerProfile srv : p.getServers()) {
|
||||||
{
|
if (srv != null && srv.name.equals(config.serverName)) {
|
||||||
if(srv != null && srv.name.equals(config.serverName)) {
|
|
||||||
this.serverProfile = srv;
|
this.serverProfile = srv;
|
||||||
this.profile = p;
|
this.profile = p;
|
||||||
Launcher.profile = p;
|
Launcher.profile = p;
|
||||||
|
@ -92,7 +91,7 @@ public boolean auth() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isFound) break;
|
if (isFound) break;
|
||||||
}
|
}
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
LogHelper.warning("Not connected to ServerProfile. May be serverName incorrect?");
|
LogHelper.warning("Not connected to ServerProfile. May be serverName incorrect?");
|
||||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
||||||
Subproject commit a246b4a966c428e626258b1e295a6c83673ab5a2
|
Subproject commit 8fd133947a9316de7b0abb7980ed0d8cb310e246
|
Loading…
Reference in a new issue