268 lines
10 KiB
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;
|
|
}
|
|
}
|
|
}
|