Server start refactoring, tutorial system
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
87dbca480e
Commit
908e54fedd
@ -120,10 +120,10 @@ public class BungeeCore extends Plugin {
|
||||
new ListCommand();
|
||||
new StatCommand();
|
||||
new VerifyCommand();
|
||||
new ReplayCommand();
|
||||
new GDPRQuery();
|
||||
new PlaytimeCommand();
|
||||
new ArenaCommand();
|
||||
new RankCommand();
|
||||
|
||||
// Punishment Commands:
|
||||
new PunishmentCommand("ban", Punishment.PunishmentType.Ban);
|
||||
@ -140,7 +140,8 @@ public class BungeeCore extends Plugin {
|
||||
new ChallengeCommand();
|
||||
new HistoricCommand();
|
||||
new CheckCommand();
|
||||
new RankCommand();
|
||||
new ReplayCommand();
|
||||
new TutorialCommand();
|
||||
|
||||
new Broadcaster();
|
||||
}else{
|
||||
|
@ -64,12 +64,13 @@ public class EventStarter implements Runnable {
|
||||
|
||||
Team blue = Team.get(next.getTeamBlue());
|
||||
Team red = Team.get(next.getTeamRed());
|
||||
String serverName = blue.getTeamKuerzel() + " vs " + red.getTeamKuerzel();
|
||||
Subserver subserver = SubserverSystem.startEventArena(next, serverName);
|
||||
ServerStarter starter = new ServerStarter().event(next);
|
||||
|
||||
ProxiedPlayer leiter = ProxyServer.getInstance().getPlayer(SteamwarUser.get(next.getKampfleiter()).getUuid());
|
||||
if(leiter != null)
|
||||
SubserverSystem.sendPlayer(subserver, leiter);
|
||||
starter.send(leiter);
|
||||
|
||||
Subserver subserver = starter.start();
|
||||
|
||||
eventServer.put(blue.getTeamId(), subserver);
|
||||
eventServer.put(red.getTeamId(), subserver);
|
||||
|
272
src/de/steamwar/bungeecore/ServerStarter.java
Normale Datei
272
src/de/steamwar/bungeecore/ServerStarter.java
Normale Datei
@ -0,0 +1,272 @@
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import de.steamwar.bungeecore.sql.Tutorial;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ServerStarter {
|
||||
|
||||
private static final boolean MAIN_SERVER = ProxyServer.getInstance().getConfig().getListeners().stream().anyMatch(info -> ((InetSocketAddress) info.getSocketAddress()).getPort() == 25565);
|
||||
private static final Portrange BAU_PORTS = MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200);
|
||||
private static final Portrange ARENA_PORTS = MAIN_SERVER ? new Portrange(3000, 3100) : (BungeeCore.EVENT_MODE ? new Portrange(4000, 5000) : BAU_PORTS);
|
||||
|
||||
private static final String BACKBONE = "/home/minecraft/";
|
||||
private static final String SERVER_PATH = BACKBONE + "server/";
|
||||
private static final String EVENT_PATH = BACKBONE + "event/";
|
||||
public static final String TEMP_WORLD_PATH = BACKBONE + "arenaserver/";
|
||||
public static final String TUTORIAL_PATH = BACKBONE + "tutorials/";
|
||||
|
||||
private File directory = null;
|
||||
private String worldDir = null;
|
||||
|
||||
private Node node = null;
|
||||
private String serverJar = "spigot-1.15.2.jar";
|
||||
private String xmx = "768M";
|
||||
private Portrange portrange = BAU_PORTS;
|
||||
private Function<Integer, String> serverNameProvider = port -> node.getName() + port;
|
||||
private BooleanSupplier startCondition = () -> true;
|
||||
private ServerConstructor constructor = (serverName, port, builder, shutdownCallback) -> new Subserver(Servertype.ARENA, serverName, port, builder, shutdownCallback);
|
||||
private Runnable worldSetup = () -> {};
|
||||
private String worldName = null;
|
||||
private Runnable worldCleanup = () -> {};
|
||||
|
||||
private final Set<ProxiedPlayer> playersToSend = new HashSet<>();
|
||||
private final Map<String, String> arguments = new HashMap<>();
|
||||
|
||||
public ServerStarter arena(ArenaMode mode, String map) {
|
||||
portrange = ARENA_PORTS;
|
||||
serverNameProvider = port -> mode.getChatName() + (port - portrange.start);
|
||||
serverJar = mode.serverJar();
|
||||
directory = new File(SERVER_PATH, mode.getFolder());
|
||||
arguments.put("config", mode.getConfig());
|
||||
tempWorld(SERVER_PATH + mode.getFolder() + "/arenas/" + map);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter event(EventFight eventFight) {
|
||||
arena(eventFight.getSpielmodus(), eventFight.getMap());
|
||||
node = Node.local;
|
||||
worldDir = EVENT_PATH;
|
||||
worldCleanup = () -> {};
|
||||
arguments.put("fightID", String.valueOf(eventFight.getFightID()));
|
||||
|
||||
String serverName = Team.get(eventFight.getTeamBlue()).getTeamKuerzel() + " vs " + Team.get(eventFight.getTeamRed()).getTeamKuerzel();
|
||||
serverNameProvider = port -> serverName;
|
||||
worldName = serverToWorldName(serverName + eventFight.getStartTime().toLocalDateTime().format(DateTimeFormatter.ISO_TIME));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter test(ArenaMode mode, String map, ProxiedPlayer owner) {
|
||||
arena(mode, map);
|
||||
buildWithTemp(owner);
|
||||
portrange = BAU_PORTS;
|
||||
arguments.put("fightID", String.valueOf(-1));
|
||||
return send(owner);
|
||||
}
|
||||
|
||||
public ServerStarter blueLeader(ProxiedPlayer player) {
|
||||
arguments.put("blueLeader", player.getUniqueId().toString());
|
||||
return send(player);
|
||||
}
|
||||
|
||||
public ServerStarter redLeader(ProxiedPlayer player) {
|
||||
arguments.put("redLeader", player.getUniqueId().toString());
|
||||
return send(player);
|
||||
}
|
||||
|
||||
public ServerStarter check(int schemID) {
|
||||
arguments.put("checkSchemID", String.valueOf(schemID));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter prepare(int schemID) {
|
||||
arguments.put("prepareSchemID", String.valueOf(schemID));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter replay(int replayID) {
|
||||
arguments.put("replay", String.valueOf(replayID));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter build15(UUID owner) {
|
||||
directory = new File(SERVER_PATH, "Bau15");
|
||||
worldDir = BungeeCore.USERWORLDS15;
|
||||
worldName = String.valueOf(SteamwarUser.get(owner).getId());
|
||||
buildWithWorld(owner, BungeeCore.BAUWELT15);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter build12(UUID owner) {
|
||||
directory = new File(SERVER_PATH, "UserBau");
|
||||
serverJar = "spigot-1.12.2.jar";
|
||||
xmx = "256M";
|
||||
worldDir = BungeeCore.WORLD_FOLDER;
|
||||
worldName = owner.toString();
|
||||
buildWithWorld(owner, BungeeCore.BAUWELT_PROTOTYP);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter tutorial(ProxiedPlayer owner, Tutorial tutorial) {
|
||||
directory = new File(SERVER_PATH, "Tutorial");
|
||||
buildWithTemp(owner);
|
||||
tempWorld(TUTORIAL_PATH + tutorial.id());
|
||||
arguments.put("tutorial", String.valueOf(tutorial.id()));
|
||||
return send(owner);
|
||||
}
|
||||
|
||||
private void tempWorld(String template) {
|
||||
worldDir = TEMP_WORLD_PATH;
|
||||
worldSetup = () -> copyWorld(node, template, worldDir + worldName);
|
||||
worldCleanup = () -> SubserverSystem.deleteFolder(node, worldDir + worldName);
|
||||
}
|
||||
|
||||
private void buildWithWorld(UUID owner, String prototype) {
|
||||
build(owner);
|
||||
|
||||
worldSetup = () -> {
|
||||
File world = new File(worldDir, worldName);
|
||||
if (!world.exists())
|
||||
copyWorld(node, prototype, world.getPath());
|
||||
};
|
||||
|
||||
// Send players to existing server
|
||||
startCondition = () -> {
|
||||
for(Subserver subserver : Subserver.getServerList()) {
|
||||
if(subserver.getType() == Servertype.BAUSERVER && ((Bauserver)subserver).getOwner().equals(owner)) {
|
||||
for(ProxiedPlayer p : playersToSend)
|
||||
SubserverSystem.sendPlayer(subserver, p);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
private void buildWithTemp(ProxiedPlayer owner) {
|
||||
build(owner.getUniqueId());
|
||||
|
||||
// Stop existing build server
|
||||
startCondition = () -> {
|
||||
if(startingBau(owner))
|
||||
return false;
|
||||
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(owner.getUniqueId()) && subserver.hasStarted()) {
|
||||
subserver.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !startingBau(owner);
|
||||
};
|
||||
}
|
||||
|
||||
private void build(UUID owner) {
|
||||
constructor = (serverName, port, builder, shutdownCallback) -> new Bauserver(serverName, owner, port, builder, shutdownCallback);
|
||||
serverNameProvider = port -> bauServerName(SteamwarUser.get(owner));
|
||||
}
|
||||
|
||||
public ServerStarter send(ProxiedPlayer player) {
|
||||
playersToSend.add(player);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Subserver start() {
|
||||
if(!startCondition.getAsBoolean())
|
||||
return null;
|
||||
|
||||
int port = portrange.freePort();
|
||||
String serverName = serverNameProvider.apply(port);
|
||||
|
||||
if(node == null)
|
||||
node = Node.getNode();
|
||||
if(worldName == null)
|
||||
worldName = serverToWorldName(serverName);
|
||||
|
||||
worldSetup.run();
|
||||
arguments.put("logPath", worldName);
|
||||
|
||||
Subserver subserver = constructor.construct(serverName, port, node.startServer(
|
||||
serverJar, directory, worldDir, worldName, port, xmx, (String[]) arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray()
|
||||
), worldCleanup);
|
||||
|
||||
for(ProxiedPlayer p : playersToSend)
|
||||
SubserverSystem.sendPlayer(subserver, p);
|
||||
|
||||
return subserver;
|
||||
}
|
||||
|
||||
private static boolean startingBau(ProxiedPlayer p) {
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && !subserver.hasStarted()) {
|
||||
Message.send("BAU_START_ALREADY", p);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String bauServerName(SteamwarUser user) {
|
||||
return user.getUserName() + "s Bau";
|
||||
}
|
||||
|
||||
public static String serverToWorldName(String serverName) {
|
||||
return serverName.replace(' ', '_').replace("[", "").replace("]", "");
|
||||
}
|
||||
|
||||
public static void copyWorld(Node node, String template, String target) {
|
||||
node.execute("cp", "-r", template, target);
|
||||
}
|
||||
|
||||
private interface ServerConstructor {
|
||||
Subserver construct(String serverName, int port, ProcessBuilder builder, Runnable shutdownCallback);
|
||||
}
|
||||
|
||||
private static class Portrange {
|
||||
|
||||
private final int start;
|
||||
private final int end;
|
||||
private int current;
|
||||
|
||||
private Portrange(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
current = start;
|
||||
}
|
||||
|
||||
private void increment() {
|
||||
current++;
|
||||
|
||||
if(current == end)
|
||||
current = start;
|
||||
}
|
||||
|
||||
private synchronized int freePort() {
|
||||
Set<Integer> usedPorts;
|
||||
|
||||
synchronized (Subserver.getServerList()) {
|
||||
usedPorts = Subserver.getServerList().stream().map(server -> ((InetSocketAddress) server.getServer().getSocketAddress()).getPort()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
while(usedPorts.contains(current)) {
|
||||
increment();
|
||||
}
|
||||
|
||||
int result = current;
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,157 +21,21 @@ package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.comms.handlers.FightInfoHandler;
|
||||
import de.steamwar.bungeecore.comms.packets.StartingServerPacket;
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import de.steamwar.bungeecore.sql.IgnoreSystem;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SubserverSystem {
|
||||
private SubserverSystem(){}
|
||||
|
||||
private static final String BACKBONE = "/home/minecraft/";
|
||||
private static final String ARENA_PATH = BACKBONE + "arenaserver/";
|
||||
private static final String SERVER_PATH = BACKBONE + "server/";
|
||||
private static final String EVENT_PATH = BACKBONE + "event/";
|
||||
|
||||
private static final boolean MAIN_SERVER = ProxyServer.getInstance().getConfig().getListeners().stream().anyMatch(info -> ((InetSocketAddress) info.getSocketAddress()).getPort() == 25565);
|
||||
private static final Portrange bauPorts = MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200);
|
||||
private static final Portrange arenaPorts = MAIN_SERVER ? new Portrange(3000, 3100) : (BungeeCore.EVENT_MODE ? new Portrange(4000, 5000) : bauPorts);
|
||||
|
||||
/**
|
||||
* This function starts every arena (even test- and eventarenas).
|
||||
*
|
||||
* @param modus
|
||||
* This has to be a valid arena mode
|
||||
*
|
||||
* @param map
|
||||
* This String must be the internal map name of the selected map
|
||||
*
|
||||
* @param eventFightID
|
||||
* For a normal arena: 0
|
||||
* For a test arena: -1
|
||||
* For an event arena: EventFightID of the fight
|
||||
*
|
||||
* @param replayID
|
||||
* @param serverName
|
||||
* The name of the server (for event and test arenas)
|
||||
* or null (autogenerated arena name modus.getDisplayName() + number)
|
||||
*
|
||||
* @param mapName
|
||||
* The name of the map copy the server runs on (for event and test arenas)
|
||||
* or null (autogenerated map name equals server name)
|
||||
*
|
||||
* @param player1
|
||||
* For event and normal arenas: The UUID of the designated leader for the blue team
|
||||
* or null (no designated leader).
|
||||
* For test arenas: The owner's UUID of the test arena (disables normal function).
|
||||
*
|
||||
* @param player2
|
||||
* For event, test and normal arenas: The UUID of the designated leader for the red team
|
||||
* or null (no designated leader).
|
||||
*
|
||||
* @return
|
||||
* The new started subserver.
|
||||
*/
|
||||
public static synchronized Subserver startArena(ArenaMode modus, String map, int eventFightID, int checkSchemID, int prepareSchemID, int replayID, String serverName, String mapName, UUID player1, UUID player2){
|
||||
//Generate missing parameters
|
||||
Node node = eventFightID > 0 ? Node.local : Node.getNode();
|
||||
int port = arenaPorts.freePort();
|
||||
|
||||
if(serverName == null){
|
||||
serverName = modus.getDisplayName() + (port - arenaPorts.start);
|
||||
}
|
||||
if(mapName == null)
|
||||
mapName = serverName;
|
||||
|
||||
mapName = mapName.replace(' ', '_').replace("[", "").replace("]", "");
|
||||
|
||||
String worldDir;
|
||||
if(eventFightID > 0)
|
||||
worldDir = EVENT_PATH;
|
||||
else
|
||||
worldDir = ARENA_PATH;
|
||||
|
||||
//Copy world
|
||||
node.execute("cp", "-r", SERVER_PATH + modus.getFolder() + "/arenas/" + map, worldDir + mapName);
|
||||
|
||||
File directory = new File(SERVER_PATH, modus.getFolder());
|
||||
ProcessBuilder builder = node.startServer(
|
||||
modus.serverJar(), directory, worldDir, mapName, port, "768M",
|
||||
"logPath=" + mapName, "config=" + modus.getConfig(),
|
||||
"fightID=" + eventFightID,
|
||||
"checkSchemID=" + checkSchemID, "prepareSchemID=" + prepareSchemID,
|
||||
"replay=" + replayID,
|
||||
player1 != null && eventFightID != -1 ? "blueLeader=" + player1 : null,
|
||||
player2 != null ? "redLeader=" + player2 : null
|
||||
);
|
||||
|
||||
String finalMapName = mapName;
|
||||
if(eventFightID == -1)
|
||||
return new Bauserver(serverName, player1, port, builder, () -> deleteFolder(node, ARENA_PATH + finalMapName));
|
||||
else
|
||||
return new Subserver(Servertype.ARENA, serverName, port, builder, () -> {
|
||||
if(eventFightID > 0)
|
||||
return;
|
||||
deleteFolder(node, ARENA_PATH + finalMapName);
|
||||
});
|
||||
}
|
||||
|
||||
public static void deleteFolder(Node node, String worldName){
|
||||
public static void deleteFolder(Node node, String worldName) {
|
||||
node.execute("rm", "-r", worldName);
|
||||
}
|
||||
|
||||
public static Subserver startEventArena(EventFight eventFight, String serverName){
|
||||
return startArena(
|
||||
eventFight.getSpielmodus(),
|
||||
eventFight.getMap(),
|
||||
eventFight.getFightID(),
|
||||
0,
|
||||
0,
|
||||
0, serverName,
|
||||
serverName + eventFight.getStartTime().toLocalDateTime().format(DateTimeFormatter.ISO_TIME),
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
public static void startTestServer(ProxiedPlayer p, ArenaMode m, String map, int checkSchemId, int prepareSchemId){
|
||||
sendPlayer(startArena(m, map, -1, checkSchemId, prepareSchemId, 0, p.getName() + "s Bau", p.getName(), p.getUniqueId(), null), p);
|
||||
}
|
||||
|
||||
private static synchronized void sendToBau(ProxiedPlayer p, UUID owner, String prototype, String worldFolder, String serverJar, String worldDir, String worldName, String xmx, String serverName){
|
||||
if(bauRunning(p, owner))
|
||||
return;
|
||||
|
||||
copyBauweltIfRequired(prototype, worldFolder + worldName);
|
||||
SteamwarUser user = SteamwarUser.get(owner);
|
||||
File directory = new File(SERVER_PATH, serverName);
|
||||
Node node = Node.getNode();
|
||||
int port = bauPorts.freePort();
|
||||
|
||||
|
||||
sendPlayer(new Bauserver(user.getUserName() + "s Bau", owner, port, node.startServer(
|
||||
serverJar, directory, worldDir, worldName, port, xmx, "logPath=" + worldName
|
||||
), () -> {}), p);
|
||||
}
|
||||
|
||||
public static void sendToBauServer(ProxiedPlayer p, UUID owner){
|
||||
sendToBau(p, owner, BungeeCore.BAUWELT_PROTOTYP, BungeeCore.WORLD_FOLDER, "spigot-1.12.2.jar", "/home/minecraft/userworlds", owner.toString(), "256M", "UserBau");
|
||||
}
|
||||
|
||||
public static void sendToBau15(ProxiedPlayer p, UUID owner){
|
||||
SteamwarUser user = SteamwarUser.get(owner);
|
||||
sendToBau(p, owner, BungeeCore.BAUWELT15, BungeeCore.USERWORLDS15, "spigot-1.15.2.jar", "/home/minecraft/userworlds15", String.valueOf(user.getId()), "768M", "Bau15");
|
||||
}
|
||||
|
||||
public static void sendDeniedMessage(ProxiedPlayer p, UUID owner){
|
||||
ProxiedPlayer o = ProxyServer.getInstance().getPlayer(owner);
|
||||
if(o == null)
|
||||
@ -191,57 +55,4 @@ public class SubserverSystem {
|
||||
if(!subserver.hasStarted() && FightInfoHandler.onLobby(player))
|
||||
new StartingServerPacket(SteamwarUser.get(player.getUniqueId())).send(player);
|
||||
}
|
||||
|
||||
private static boolean bauRunning(ProxiedPlayer p, UUID owner){
|
||||
for(Subserver subserver : Subserver.getServerList()){
|
||||
if(subserver.getType() == Servertype.BAUSERVER && ((Bauserver)subserver).getOwner().equals(owner)){
|
||||
sendPlayer(subserver, p);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void copyBauweltIfRequired(String sourcePath, String targetPath){
|
||||
File w = new File(targetPath);
|
||||
if (!w.exists() || !w.isDirectory())
|
||||
Node.local.execute("cp", "-r", sourcePath, targetPath);
|
||||
}
|
||||
|
||||
|
||||
private static class Portrange {
|
||||
|
||||
private final int start;
|
||||
private final int end;
|
||||
private int current;
|
||||
|
||||
private Portrange(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
current = start;
|
||||
}
|
||||
|
||||
private void increment() {
|
||||
current++;
|
||||
|
||||
if(current == end)
|
||||
current = start;
|
||||
}
|
||||
|
||||
private synchronized int freePort() {
|
||||
Set<Integer> usedPorts;
|
||||
|
||||
synchronized (Subserver.getServerList()) {
|
||||
usedPorts = Subserver.getServerList().stream().map(server -> ((InetSocketAddress) server.getServer().getSocketAddress()).getPort()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
while(usedPorts.contains(current)) {
|
||||
increment();
|
||||
}
|
||||
|
||||
int result = current;
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,20 +45,17 @@ public class BauCommand extends BasicCommand {
|
||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
||||
|
||||
if(args.length == 0){
|
||||
if(bau15(p, args, 0))
|
||||
SubserverSystem.sendToBau15(p, p.getUniqueId());
|
||||
else
|
||||
SubserverSystem.sendToBauServer(p, p.getUniqueId());
|
||||
(bau15(p, args, 0) ? new ServerStarter().build15(p.getUniqueId()) : new ServerStarter().build12(p.getUniqueId())).send(p).start();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(args[0].toLowerCase()){
|
||||
case "ws":
|
||||
case "warship":
|
||||
case "12":
|
||||
case "1.12":
|
||||
SubserverSystem.sendToBauServer(p, p.getUniqueId());
|
||||
new ServerStarter().build12(p.getUniqueId()).send(p).start();
|
||||
break;
|
||||
case "ws":
|
||||
case "warship":
|
||||
case "as":
|
||||
case "airship":
|
||||
case "mwg":
|
||||
@ -67,7 +64,7 @@ public class BauCommand extends BasicCommand {
|
||||
case "wargear":
|
||||
case "15":
|
||||
case "1.15":
|
||||
SubserverSystem.sendToBau15(p, p.getUniqueId());
|
||||
new ServerStarter().build15(p.getUniqueId()).send(p).start();
|
||||
break;
|
||||
case "addmember":
|
||||
addmember(p, args);
|
||||
@ -143,10 +140,7 @@ public class BauCommand extends BasicCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
if(bau15(p, args, 2))
|
||||
SubserverSystem.sendToBau15(p, worldOwner.getUuid());
|
||||
else
|
||||
SubserverSystem.sendToBauServer(p, worldOwner.getUuid());
|
||||
(bau15(p, args, 2) ? new ServerStarter().build15(worldOwner.getUuid()) : new ServerStarter().build12(worldOwner.getUuid())).send(p).start();
|
||||
}
|
||||
|
||||
private static boolean bau15(ProxiedPlayer p, String[] args, int pos){
|
||||
@ -259,40 +253,8 @@ public class BauCommand extends BasicCommand {
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean startingBau(ProxiedPlayer p) {
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && !subserver.hasStarted()) {
|
||||
Message.send("BAU_START_ALREADY", p);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean stopBauserver(ProxiedPlayer p){
|
||||
if(startingBau(p))
|
||||
return false;
|
||||
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && subserver.hasStarted()) {
|
||||
subserver.stop();
|
||||
try {
|
||||
Thread.sleep(200); // Wait until possible testarena-World has been deleted
|
||||
} catch (InterruptedException e) {
|
||||
throw new SecurityException("Subserver stop interrupted", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !startingBau(p);
|
||||
}
|
||||
|
||||
private static void testarena(ProxiedPlayer p, String[] args){
|
||||
FightCommand.createArena(p, "/bau testarena ", args, 1, false, (player, mode, map) -> ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
||||
if(stopBauserver(p))
|
||||
SubserverSystem.startTestServer(p, mode, map, 0, 0);
|
||||
}));
|
||||
FightCommand.createArena(p, "/bau testarena ", args, 1, false, (player, mode, map) -> ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> new ServerStarter().test(mode, map, p).start()));
|
||||
}
|
||||
|
||||
private static BauweltMember member(ProxiedPlayer p, SteamwarUser member){
|
||||
|
@ -76,11 +76,7 @@ public class ChallengeCommand extends BasicCommand {
|
||||
challenges.remove(target);
|
||||
challenges.remove(player);
|
||||
|
||||
Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), target.getUniqueId());
|
||||
|
||||
SubserverSystem.sendPlayer(arena, player);
|
||||
SubserverSystem.sendPlayer(arena, target);
|
||||
|
||||
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).redLeader(target).start();
|
||||
Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER",
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName(), target.getName());
|
||||
}else{
|
||||
|
@ -228,13 +228,12 @@ public class CheckCommand extends BasicCommand {
|
||||
this.checkList = checkQuestions.get(schematic.getSchemtype()).listIterator();
|
||||
|
||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
||||
if(!BauCommand.stopBauserver(checker)){
|
||||
ArenaMode mode = ArenaMode.getBySchemType(schematic.getSchemtype().fightType());
|
||||
if(new ServerStarter().test(mode, mode.getRandomMap(), checker).check(schematic.getId()).start() == null) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaMode mode = ArenaMode.getBySchemType(schematic.getSchemtype().fightType());
|
||||
SubserverSystem.startTestServer(checker, mode, FightCommand.getMap(checker, mode, "Random"), schematic.getId(), 0);
|
||||
currentCheckers.put(checker.getUniqueId(), this);
|
||||
currentSchems.put(schematic.getId(), this);
|
||||
for(CheckedSchematic previous : CheckedSchematic.previousChecks(schematic))
|
||||
|
@ -164,8 +164,7 @@ public class FightCommand extends BasicCommand {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
createArena(sender, "/fight ", args, 0, false, (player, mode, map) -> {
|
||||
Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null);
|
||||
SubserverSystem.sendPlayer(arena, player);
|
||||
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).start();
|
||||
Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER"
|
||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName());
|
||||
});
|
||||
|
@ -19,10 +19,7 @@
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.ArenaMode;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.Subserver;
|
||||
import de.steamwar.bungeecore.SubserverSystem;
|
||||
import de.steamwar.bungeecore.*;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
|
||||
@ -36,8 +33,7 @@ public class HistoricCommand extends BasicCommand {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
FightCommand.createArena(sender, "/historic ", args, 0, true, (player, mode, map) -> {
|
||||
Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null);
|
||||
SubserverSystem.sendPlayer(arena, player);
|
||||
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).start();
|
||||
Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER"
|
||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName());
|
||||
});
|
||||
|
@ -19,9 +19,7 @@
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.ArenaMode;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.SubserverSystem;
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.inventory.SWItem;
|
||||
import de.steamwar.bungeecore.inventory.SWListInv;
|
||||
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
||||
@ -49,16 +47,16 @@ public class ReplayCommand extends BasicCommand {
|
||||
|
||||
new SWStreamInv<>(player, Message.parse("REPLAY_TITLE", player), (click, fight) -> {
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
boolean adminReplay = false;
|
||||
ArenaMode mode = fight.getGameMode();
|
||||
ServerStarter starter = new ServerStarter().replay(fight.getFightID()).blueLeader(player);
|
||||
|
||||
if (user.getUserGroup().isAdminGroup() && click.isShiftClick() && fight.replayExists()) {
|
||||
adminReplay = true;
|
||||
starter.test(mode, mode.getRandomMap(), player).start();
|
||||
} else if(!fight.replayAllowed()) {
|
||||
Message.send("REPLAY_UNAVAILABLE", player);
|
||||
return;
|
||||
} else {
|
||||
starter.arena(mode, mode.getRandomMap()).start();
|
||||
}
|
||||
ArenaMode mode = fight.getGameMode();
|
||||
|
||||
SubserverSystem.sendPlayer(SubserverSystem.startArena(mode, mode.getRandomMap(), adminReplay ? -1 : 0, 0, 0, fight.getFightID(), null, null, null, null), player);
|
||||
}, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(player, fight), fight)).collect(Collectors.toList())).open();
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,20 @@
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.inventory.SWItem;
|
||||
import de.steamwar.bungeecore.inventory.SWListInv;
|
||||
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.Tutorial;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TutorialCommand extends BasicCommand {
|
||||
@ -43,12 +47,47 @@ public class TutorialCommand extends BasicCommand {
|
||||
return;
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
//TODO: Tutorial rating
|
||||
//TODO: Tutorial creation
|
||||
if(args.length != 0) {
|
||||
switch(args[0]) {
|
||||
case "rate":
|
||||
if(args.length < 2) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "rate executed with missing argument");
|
||||
return;
|
||||
}
|
||||
|
||||
new SWStreamInv<>(player, Message.parse("TUTORIAL_TITLE", player), (click, tutorial) -> {
|
||||
//TODO: Tutorial start
|
||||
}, page -> Tutorial.getPage(page, 45).stream().map(tutorial -> new SWListInv.SWListEntry<>(getTutorialItem(player, tutorial), tutorial)).collect(Collectors.toList())).open();
|
||||
int id;
|
||||
try {
|
||||
id = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "rate executed with non number: " + args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
Tutorial tutorial = Tutorial.get(id);
|
||||
if(tutorial == null) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "rate executed with nonexistent id: " + id);
|
||||
return;
|
||||
}
|
||||
|
||||
rate(player, tutorial);
|
||||
break;
|
||||
case "create":
|
||||
if(args.length < 3) {
|
||||
Message.send("TUTORIAL_CREATE_HELP", player);
|
||||
return;
|
||||
}
|
||||
|
||||
String material = args[1].toUpperCase();
|
||||
String name = Arrays.stream(args).skip(2).collect(Collectors.joining(" "));
|
||||
create(player, name, material);
|
||||
break;
|
||||
default:
|
||||
Message.send("TUTORIAL_CREATE_HELP", player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
new SWStreamInv<>(player, Message.parse("TUTORIAL_TITLE", player), (click, tutorial) -> new ServerStarter().tutorial(player, tutorial).start(), page -> Tutorial.getPage(page, 45).stream().map(tutorial -> new SWListInv.SWListEntry<>(getTutorialItem(player, tutorial), tutorial)).collect(Collectors.toList())).open();
|
||||
}
|
||||
|
||||
private SWItem getTutorialItem(ProxiedPlayer player, Tutorial tutorial) {
|
||||
@ -56,12 +95,44 @@ public class TutorialCommand extends BasicCommand {
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
lore.add(Message.parse("TUTORIAL_BY", player, tutorial.creator().getUserName()));
|
||||
lore.add("");
|
||||
lore.add(Message.parse("TUTORIAL_BASED_ON", player));
|
||||
lore.add(Message.parse("TUTORIAL_NAME", player, tutorial.parent().name()));
|
||||
lore.add(Message.parse("TUTORIAL_BY", player, tutorial.parent().creator().getUserName()));
|
||||
item.setLore(lore);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void rate(ProxiedPlayer player, Tutorial tutorial) {
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
int[] rates = new int[]{1, 2, 3, 4, 5};
|
||||
|
||||
new SWListInv<>(player, Message.parse("TUTORIAL_RATE_TITLE", player), Arrays.stream(rates).mapToObj(rate -> new SWListInv.SWListEntry<>(new SWItem("NETHER_STAR", Message.parse("TUTORIAL_RATE", player, rate)), rate)).collect(Collectors.toList()), (click, rate) -> {
|
||||
tutorial.rate(user, rate);
|
||||
}).open();
|
||||
}
|
||||
|
||||
private void create(ProxiedPlayer player, String name, String item) {
|
||||
Subserver subserver = Subserver.getSubserver(player);
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
File tempWorld = new File(ServerStarter.TEMP_WORLD_PATH, ServerStarter.serverToWorldName(ServerStarter.bauServerName(user)));
|
||||
|
||||
if(subserver == null || !subserver.hasStarted() || subserver.getType() != Servertype.BAUSERVER || !tempWorld.exists()) {
|
||||
Message.send("TUTORIAL_CREATE_MISSING", player);
|
||||
return;
|
||||
}
|
||||
|
||||
subserver.execute("save-all");
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
BungeeCore.get().getLogger().log(Level.WARNING, "Tutorial creation interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
Tutorial tutorial = Tutorial.create(user, name, item);
|
||||
File tutorialWorld = new File(ServerStarter.TUTORIAL_PATH, String.valueOf(tutorial.id()));
|
||||
|
||||
if (tutorialWorld.exists())
|
||||
SubserverSystem.deleteFolder(Node.local, tutorialWorld.getPath());
|
||||
ServerStarter.copyWorld(Node.local, tempWorld.getPath(), tutorialWorld.getPath());
|
||||
Message.send("TUTORIAL_CREATED", player);
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ package de.steamwar.bungeecore.comms.handlers;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import de.steamwar.bungeecore.ArenaMode;
|
||||
import de.steamwar.bungeecore.SubserverSystem;
|
||||
import de.steamwar.bungeecore.commands.BauCommand;
|
||||
import de.steamwar.bungeecore.ServerStarter;
|
||||
import de.steamwar.bungeecore.comms.SpigotHandler;
|
||||
import de.steamwar.bungeecore.sql.SchematicType;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
@ -37,7 +36,6 @@ public class PrepareSchemHandler implements SpigotHandler {
|
||||
int schematicID = in.readInt();
|
||||
ArenaMode mode = ArenaMode.getBySchemType(SchematicType.fromDB(in.readUTF()));
|
||||
|
||||
BauCommand.stopBauserver(player);
|
||||
SubserverSystem.startTestServer(player, mode, mode.getRandomMap(), 0, schematicID);
|
||||
new ServerStarter().test(mode, mode.getRandomMap(), player).prepare(schematicID).start();
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,14 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Tutorial {
|
||||
|
||||
private static final Statement by_popularity = new Statement("SELECT t.TutorialID, t.Creator, t.Name, t.Item, AVG(r.Stars) AS Stars, p.TutorialID AS ParentID, p.Creator AS ParentCreator, p.Name AS ParentName FROM Tutorial t INNER JOIN Tutorial p ON t.Parent = p.TutorialID LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID GROUP BY t.TutorialID ORDER BY SUM(r.Stars) DESC LIMIT ?, ?");
|
||||
private static final Statement by_popularity = new Statement("SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID GROUP BY t.TutorialID ORDER BY SUM(r.Stars) DESC LIMIT ?, ?");
|
||||
private static final Statement by_creator_name = new Statement("SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.Creator = ? AND t.Name = ? GROUP BY t.TutorialID");
|
||||
private static final Statement by_id = new Statement("SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.TutorialID = ? GROUP BY t.TutorialID");
|
||||
private static final Statement rate = new Statement("INSERT INTO TutorialRating (TutorialID, UserID, Stars) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Stars = VALUES(Stars)");
|
||||
private static final Statement create = new Statement("INSERT INTO Tutorial (Creator, Name, Item, Parent) VALUES (?, ?, ?, ?)");
|
||||
private static final Statement create = new Statement("INSERT INTO Tutorial (Creator, Name, Item) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Item = VALUES(Item)");
|
||||
|
||||
public static List<Tutorial> getPage(int page, int elementsPerPage) {
|
||||
List<Tutorial> tutorials = by_popularity.select(rs -> {
|
||||
@ -40,24 +41,34 @@ public class Tutorial {
|
||||
return t;
|
||||
}, page * elementsPerPage, elementsPerPage);
|
||||
|
||||
SteamwarUser.batchCache(tutorials.stream().flatMap(tutorial -> Stream.of(tutorial.creator, tutorial.parent.creator)).collect(Collectors.toSet()));
|
||||
SteamwarUser.batchCache(tutorials.stream().map(tutorial -> tutorial.creator).collect(Collectors.toSet()));
|
||||
return tutorials;
|
||||
}
|
||||
|
||||
public static void create(SteamwarUser creator, String name, Tutorial parent) {
|
||||
create.update(creator.getId(), name, parent.id);
|
||||
public static Tutorial create(SteamwarUser creator, String name, String item) {
|
||||
create.update(creator.getId(), name, item);
|
||||
return by_creator_name.select(rs -> {
|
||||
rs.next();
|
||||
return new Tutorial(rs);
|
||||
}, creator.getId(), name);
|
||||
}
|
||||
|
||||
public static Tutorial get(int id) {
|
||||
return by_id.select(rs -> {
|
||||
if(rs.next())
|
||||
return new Tutorial(rs);
|
||||
return null;
|
||||
}, id);
|
||||
}
|
||||
|
||||
private final int id;
|
||||
private final int creator;
|
||||
private final String name;
|
||||
private final String item;
|
||||
private Tutorial parent;
|
||||
private final int stars;
|
||||
|
||||
public Tutorial(ResultSet rs) throws SQLException {
|
||||
this(rs.getInt("TutorialID"), rs.getInt("Creator"), rs.getString("Name"), rs.getString("Item"), rs.getInt("Stars"));
|
||||
parent = new Tutorial(rs.getInt("ParentID"), rs.getInt("ParentCreator"), rs.getString("ParentName"), "", 0);
|
||||
}
|
||||
|
||||
private Tutorial(int id, int creator, String name, String item, int stars) {
|
||||
@ -72,10 +83,6 @@ public class Tutorial {
|
||||
return SteamwarUser.get(creator);
|
||||
}
|
||||
|
||||
public Tutorial parent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public int stars() {
|
||||
return stars;
|
||||
}
|
||||
|
@ -337,7 +337,11 @@ REPLAY_SERVER=§7{0}
|
||||
TUTORIAL_TITLE=Tutorials
|
||||
TUTORIAL_NAME=§e{0}
|
||||
TUTORIAL_BY=§8von §7{0}
|
||||
TUTORIAL_BASED_ON=§8Basierend auf
|
||||
TUTORIAL_RATE_TITLE=Tutorial bewerten
|
||||
TUTORIAL_RATE=§e{0} §7Stern(e)
|
||||
TUTORIAL_CREATE_HELP=§8/§7tutorial create §8[§eMaterial§8] §8[§eName§8]
|
||||
TUTORIAL_CREATE_MISSING=§cEin Tutorial kann nur von einem Tutorialserver aus erstellt werden!
|
||||
TUTORIAL_CREATED=§7Das Tutorial wurde erstellt§8.
|
||||
|
||||
#ServerTeamchatCommand
|
||||
STC_USAGE=§8/§7stc §8[§eNachricht an das Team§8]
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren