Terrain4J_Experimental_branch/src/main/java/net/halbear/Executable/Server.java

268 lines
10 KiB
Java

package net.halbear.Executable;
import com.oracle.svm.core.annotate.Delete;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSession;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.Packet;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ServerSideNetworkUtils;
import net.halbear.Terrain4J.EngineCore.Threads.EngineThread;
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
import net.halbear.Terrain4J.EngineCore.Threads.ServerConnectionThread;
import net.halbear.Terrain4J.EngineCore.Threads.ServerSelectorMasterThread;
import org.jetbrains.annotations.NotNull;
import org.tinylog.Logger;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Server {
@Deprecated
@Delete
public static Map<UUID, ServerConnectionThread> ConnectedClients = new ConcurrentHashMap<>();
public static Map<UUID, String> ClientNames = new ConcurrentHashMap<>();
private static ServerSelectorMasterThread ServerNetworker;
public static ServerSelectorMasterThread GetServerNetworker(){
return ServerNetworker;
}
public static final Queue<Packet> OutGoingPacketQueue = new ConcurrentLinkedQueue<>();
public static final Queue<Packet> IncomingPacketQueue = new ConcurrentLinkedQueue<>();
public static void CollectIncomingPackets(){
ClientSession.GetClientSessionInstances().forEach((uuid, client)->{
client.CollectIncomingPackets(IncomingPacketQueue);
});
}
@Deprecated
public static void LegacyCollectIncomingPackets(){
ConnectedClients.forEach((uuid,client)->{
client.CollectIncomingPackets(IncomingPacketQueue);
});
}
public static void ProcessIncomingPackets(){
Packet packet;
while((packet = IncomingPacketQueue.poll()) != null){
ServerSideNetworkUtils.ProcessClientPacket(packet);
}
}
public static void ProcessOutgoingPackets(){
Packet packet;
ClientSession.ProcessOutboundPackets();
while((packet = OutGoingPacketQueue.poll()) != null){
ClientSession.HandOutPacket(packet);
}
}
@Deprecated
public static void LegacyProcessIncomingPackets(){
Packet packet;
while((packet = IncomingPacketQueue.poll()) != null){
ServerSideNetworkUtils.LegacyProcessClientPacket(packet);
}
}
@Deprecated
public static void LegacyProcessOutgoingPackets(){
Packet packet;
while((packet = OutGoingPacketQueue.poll()) != null){
Packet packetToSend = packet;
ConnectedClients.forEach((uuid,client)->{
client.AddOutgoingPacket(packetToSend);
});
}
}
@Deprecated
public static void LegacyRemoveClient(UUID clientID){
Logger.debug("Removing client with UUID {}",clientID);
ServerConnectionThread connection = ConnectedClients.remove(clientID);
if(connection != null){
connection.DestroyOwnedActor();
}
}
static boolean LegacyNetworking = false;
public static void StartServer(String[] args) throws IOException {
Logger.info("\nLaunching New Terrain4J Powered Software!");
RenderThread.Headless = true;
PrimaryRuntime.IsServer = true;
if(LegacyNetworking){
ServerSocket server = new ServerSocket(ServerConnectionThread.ServerPort);
Thread acceptThread = new Thread(() -> {
while(true) {
try {
Socket clientSocket = server.accept();
new Thread(new ServerConnectionThread(clientSocket)).start();
} catch (IOException e) {
Logger.error(e, "Failed to accept client connection");
}
}
}, "Terrain4J Server Connection Listener Thread");
acceptThread.start();
}
else {
ServerNetworker = new ServerSelectorMasterThread();
ServerNetworker.Initialise();
}
var GameEngine = new PrimaryRuntime(EngineConfig.getInstance().GetSoftwareName(), new GameCore());
Logger.info("Launched Terrain4J Engine");
GameEngine.run();
}
private static final Map<String, Boolean> ProfanityFilter = new HashMap<>();
private static final Map<String, String> LEET_MAP = new HashMap<>();
private static final Pattern TextFilterPattern;
static{
ProfanityFilter.put("fuck", true);
ProfanityFilter.put("shit", true);
ProfanityFilter.put("bitch", true);
ProfanityFilter.put("motherfucker",true);
ProfanityFilter.put("nigger",true);
ProfanityFilter.put("nigga",true);
ProfanityFilter.put("pussy",true);
ProfanityFilter.put("cunt",true);
ProfanityFilter.put("slut",true);
ProfanityFilter.put("whore",true);
LEET_MAP.put("(3", "ce");
LEET_MAP.put("(", "c");
LEET_MAP.put("|)", "d");
LEET_MAP.put("|", "i");
LEET_MAP.put("!", "i");
LEET_MAP.put("3", "e");
LEET_MAP.put("£", "e");
LEET_MAP.put("1", "l");
LEET_MAP.put("0", "o");
LEET_MAP.put("[]", "o");
LEET_MAP.put("{}", "o");
LEET_MAP.put("*", "o");
LEET_MAP.put("4", "a");
LEET_MAP.put("@", "a");
LEET_MAP.put("5", "s");
LEET_MAP.put("$", "s");
LEET_MAP.put("7", "t");
StringBuilder patternBuilder = new StringBuilder();
LEET_MAP.keySet().stream()
.sorted((a, b) -> Integer.compare(b.length(), a.length()))
.forEach(key -> patternBuilder.append(Pattern.quote(key)).append("|"));
String regex = patternBuilder.substring(0, patternBuilder.length() - 1);
TextFilterPattern = Pattern.compile(regex);
}
public static String ProcessStringFiltering(String TextIn){
Logger.debug("Incoming String: " + TextIn);
String AutoFileredTextIn = TextIn; //TextIn.replaceAll("[^\\dA-Za-z ]", "#");
String Lower = TextIn.toLowerCase();
Matcher matcher = TextFilterPattern.matcher(Lower);
StringBuilder result = new StringBuilder();
while (matcher.find()) {
String token = matcher.group();
String replacement = LEET_MAP.get(token);
matcher.appendReplacement(result, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(result);
return getConstructedText(result, AutoFileredTextIn);
}
@NotNull
private static String getConstructedText(StringBuilder result, String AutoFileredTextIn) {
String translated = result.toString();
Logger.debug("regex checked String: " + translated);
String[] words = translated.split("\\s+");
String[] OriginalWords = AutoFileredTextIn.split("\\s+");
String ConstructedText = "";
boolean ContainsProfanity = false;
for (int i = 0; i < words.length; i++) {
String word = words[i];
if(ProfanityFilter.containsKey(words[i])){
ConstructedText += "[Censored] ";
ContainsProfanity = true;
} else{
ConstructedText += (words.length == OriginalWords.length ? OriginalWords[i] : word) + " ";
}
}
return ConstructedText;
}
public static void ProcessCommand(String TextIn){
String formatted = TextIn.trim().toLowerCase().replace("\\s|[\\_\\-\\/\\\\]","");
switch (formatted){
case "help":
case "?":
case "helpme":
case "docs":
case "documentation":
PrimaryRuntime.printLog("Here are a list of commands!\n\t help -> list's all of the available commands\n\t stop -> stops the server with a clean shutdown\n\t quit -> forcibly kills the server\n\t stats -> server info dump\n");
break;
case "stats":
List<String[]> profiling = EngineConfig.getInstance().GetSystemProfiling();
String Profiling = "";
for(int i = 0; i < profiling.size(); i++){
Profiling += String.join("\n", profiling.get(i));
}
AtomicReference<String> PlayerConnections = new AtomicReference<>("");
if(LegacyNetworking) {
Server.ConnectedClients.forEach((uuid, client) -> {
String Username = "N/A";
if (Server.ClientNames.containsKey(uuid)) {
Username = Server.ClientNames.get(uuid);
}
PlayerConnections.set(PlayerConnections.get() + "\nConnection UUID: " + uuid.toString() + "\n\tIP address -> " + client.getIP() + "\n\tUsername -> " + Username);
});
PrimaryRuntime.printLog("\nServer Runtime Info:\n\tPlayers Connected: " + Server.ConnectedClients.size() + "\n" + PlayerConnections.get() + "\n\n" + Profiling);
} else{
ClientSession.GetClientSessionInstances().forEach((uuid, client) -> {
String Username = client.GetClientName();
PlayerConnections.set(PlayerConnections.get() + "\nConnection Instance UUID: " + uuid.toString() +"\n\tClient UUID: " + client.GetClientUUID() + "\n\tIP address -> " + client.GetIP() + "\n\tUsername -> " + Username);
});
PrimaryRuntime.printLog("\nServer Runtime Info:\n\tPlayers Connected: " + Server.ConnectedClients.size() + "\n" + PlayerConnections.get() + "\n\n" + Profiling);
}
break;
case "stop":
case "end":
PrimaryRuntime.printLog("Stopping Server");
EngineThread.running = false;
PrimaryRuntime.CanClose = true;
break;
case "quit":
case "kill":
case "exit":
System.exit(0);
break;
}
}
}