diff --git a/gradle.properties b/gradle.properties index d2941d6..2ea4430 100644 --- a/gradle.properties +++ b/gradle.properties @@ -34,7 +34,7 @@ mod_name=PlayerSync # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=GPL-3.0 license # The mod version. See https://semver.org/ -mod_version=2.1.0 +mod_version=2.1.2 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/vip/fubuki/playersync/sync/ChatSync.java b/src/main/java/vip/fubuki/playersync/sync/ChatSync.java index 3dd6e65..0414637 100644 --- a/src/main/java/vip/fubuki/playersync/sync/ChatSync.java +++ b/src/main/java/vip/fubuki/playersync/sync/ChatSync.java @@ -1,140 +1,38 @@ package vip.fubuki.playersync.sync; -import net.minecraft.network.chat.Component; -import net.minecraft.server.players.PlayerList; +import com.mojang.logging.LogUtils; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import org.slf4j.Logger; import vip.fubuki.playersync.config.JdbcConfig; +import vip.fubuki.playersync.sync.chat.ChatSyncClient; +import vip.fubuki.playersync.sync.chat.ChatSyncServer; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Objects; -import java.util.Scanner; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import org.slf4j.Logger; - -import com.mojang.logging.LogUtils; public class ChatSync { - private static final Logger LOGGER = LogUtils.getLogger(); - - static PlayerList playerList; - - static ServerSocket serverSocket; - static Socket clientSocket; - static Set SocketList = ConcurrentHashMap.newKeySet(); - static ExecutorService executorService = Executors.newCachedThreadPool(); + public static final Logger LOGGER = LogUtils.getLogger(); public static void register(){ if(JdbcConfig.IS_CHAT_SERVER.get()) { - LOGGER.info("Launching chat server thread."); - new Thread(ChatSync::ServerSocket).start(); - } - ClientSocket(); - MinecraftForge.EVENT_BUS.register(ChatSync.class); - } - - - private static void ServerSocket() { - try { LOGGER.info("Trying to setup chat server at port " + JdbcConfig.CHAT_SERVER_PORT.get()); - serverSocket = new ServerSocket(JdbcConfig.CHAT_SERVER_PORT.get()); - while (true) { - Socket newSocket = serverSocket.accept(); - SocketList.add(newSocket); - executorService.submit(() -> handleClient(newSocket)); - } - } catch (IOException e) { - LOGGER.error("Unable to start chat server"); - e.printStackTrace(); - } finally { - try { - serverSocket.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static void handleClient(Socket socket) { - try (InputStream inputStream = socket.getInputStream()) { - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) != -1) { - String message = new String(buffer, 0, bytesRead); - broadcastMessage(socket, message); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - SocketList.remove(socket); - try { - socket.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static void broadcastMessage(Socket sender, String message) { - for (Socket socket : SocketList) { - if (!socket.equals(sender)) { + new Thread(()->{ + ChatSyncServer chatSyncServer = new ChatSyncServer(); try { - OutputStream outputStream = socket.getOutputStream(); - outputStream.write(message.getBytes()); + chatSyncServer.run(); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Unable to start chat server", e); } - } + }).start(); } - } - private static void ClientSocket() { - try { + new Thread(()->{ LOGGER.info("Trying to connect to chat server " + JdbcConfig.CHAT_SERVER_IP.get() + ":" + JdbcConfig.CHAT_SERVER_PORT.get()); - clientSocket = new Socket(JdbcConfig.CHAT_SERVER_IP.get(), JdbcConfig.CHAT_SERVER_PORT.get()); - Scanner scanner = new Scanner(clientSocket.getInputStream()); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - Component textComponents = Component.nullToEmpty(line); - playerList.broadcastSystemMessage(textComponents,true); - } - } catch (IOException e) { - e.printStackTrace(); - reconnectClient(); - } - } - - private static void reconnectClient() { - LOGGER.warn("TODO: implement reconnectClient()"); - //TODO - } - - @SubscribeEvent - public static void onPlayerChat(net.minecraftforge.event.ServerChatEvent event) throws IOException { - String message= event.getUsername()+":"+event.getMessage(); - OutputStream outputStream = clientSocket.getOutputStream(); - outputStream.write(message.getBytes()); - } - - @SubscribeEvent - public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event){ - playerList= Objects.requireNonNull(event.getEntity().getServer()).getPlayerList(); - } - - @SubscribeEvent - public static void onPlayerLeave(PlayerEvent.PlayerLoggedOutEvent event){ - playerList= Objects.requireNonNull(event.getEntity().getServer()).getPlayerList(); + ChatSyncClient chatSyncClient = new ChatSyncClient(); + chatSyncClient.run(); + }).start(); + MinecraftForge.EVENT_BUS.register(ChatSyncClient.class); } } diff --git a/src/main/java/vip/fubuki/playersync/sync/chat/ChatSyncClient.java b/src/main/java/vip/fubuki/playersync/sync/chat/ChatSyncClient.java new file mode 100644 index 0000000..535e86e --- /dev/null +++ b/src/main/java/vip/fubuki/playersync/sync/chat/ChatSyncClient.java @@ -0,0 +1,65 @@ +package vip.fubuki.playersync.sync.chat; + +import net.minecraft.network.chat.Component; +import net.minecraft.server.players.PlayerList; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import vip.fubuki.playersync.PlayerSync; +import vip.fubuki.playersync.config.JdbcConfig; +import vip.fubuki.playersync.sync.ChatSync; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.Objects; + +public class ChatSyncClient { + static PlayerList playerList; + static Socket clientSocket; + static PrintWriter out; + + public void run() { + try { + clientSocket = new Socket(JdbcConfig.CHAT_SERVER_IP.get(), JdbcConfig.CHAT_SERVER_PORT.get()); + out = new PrintWriter(clientSocket.getOutputStream(),true); + + BufferedReader in = new BufferedReader( + new InputStreamReader(clientSocket.getInputStream())); + + String serverMessage; + while ((serverMessage = in.readLine()) != null) { + PlayerSync.LOGGER.info("Received message from chat server: " + serverMessage); + Component textComponents = Component.nullToEmpty(serverMessage); + playerList.broadcastSystemMessage(textComponents,false); + } + } catch (IOException e) { + e.printStackTrace(); + reconnectClient(); + } + } + + private static void reconnectClient() { + ChatSync.LOGGER.warn("TODO: implement reconnectClient()"); + //TODO + } + + @SubscribeEvent + public static void onPlayerChat(net.minecraftforge.event.ServerChatEvent event) { + String message= "<"+event.getUsername()+"> "+event.getMessage().getString(); + if (out != null) { + out.println(message); + } + } + + @SubscribeEvent + public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event){ + playerList = Objects.requireNonNull(event.getEntity().getServer()).getPlayerList(); + } + + @SubscribeEvent + public static void onPlayerLeave(PlayerEvent.PlayerLoggedOutEvent event){ + playerList = Objects.requireNonNull(event.getEntity().getServer()).getPlayerList(); + } +} diff --git a/src/main/java/vip/fubuki/playersync/sync/chat/ChatSyncServer.java b/src/main/java/vip/fubuki/playersync/sync/chat/ChatSyncServer.java new file mode 100644 index 0000000..a9ecf65 --- /dev/null +++ b/src/main/java/vip/fubuki/playersync/sync/chat/ChatSyncServer.java @@ -0,0 +1,63 @@ +package vip.fubuki.playersync.sync.chat; + +import vip.fubuki.playersync.config.JdbcConfig; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ChatSyncServer { + static ServerSocket serverSocket; + static final Set SocketList = ConcurrentHashMap.newKeySet(); + static final ExecutorService executorService = Executors.newCachedThreadPool(); + + public void run() throws IOException { + serverSocket = new ServerSocket(JdbcConfig.CHAT_SERVER_PORT.get()); + while (!Thread.currentThread().isInterrupted()) { + Socket newSocket = serverSocket.accept(); + SocketList.add(newSocket); + executorService.submit(() -> handleClient(newSocket)); + } + serverSocket.close(); + } + + private void handleClient(Socket socket) { + try (InputStream inputStream = socket.getInputStream()) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + String message = new String(buffer, 0, bytesRead); + broadcastMessage(socket, message); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + SocketList.remove(socket); + try { + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private void broadcastMessage(Socket sender, String message) { + for (Socket socket : SocketList) { + if (!socket.equals(sender)) { + try { + OutputStream outputStream = socket.getOutputStream(); + outputStream.write(message.getBytes()); + outputStream.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/src/main/resources/assets/playersync/lang/en_us.json b/src/main/resources/assets/playersync/lang/en_us.json index 8e04540..4b03f8e 100644 --- a/src/main/resources/assets/playersync/lang/en_us.json +++ b/src/main/resources/assets/playersync/lang/en_us.json @@ -1,6 +1,5 @@ { "playersync.item_placeholder_description": "Item is unknown on this server. This can either\nbe a modded item, an added, or a removed vanilla\nitem.\nThis voucher will automatically be replaced with\nthe corresponding item when joining a server\nwhere the item is known.", - "playersync.placeholder_title_override": "Item Voucher", "playersync.item_placeholder_title": "Item Voucher", "playersync.already_online": "You can't join more than one synchronization server at the same time." } diff --git a/src/main/resources/assets/playersync/lang/zh_cn.json b/src/main/resources/assets/playersync/lang/zh_cn.json index 92bbe6a..f206090 100644 --- a/src/main/resources/assets/playersync/lang/zh_cn.json +++ b/src/main/resources/assets/playersync/lang/zh_cn.json @@ -1,6 +1,5 @@ { "playersync.item_placeholder_description": "物品在此服务器未知。这可能是一个模组物品,或是不同版本的原版物品。\n这张券将会在加入可识别此物品的服务器后自动替换为对应物品。", - "playersync.placeholder_title_override": "物品券", "playersync.item_placeholder_title": "物品券", "playersync.already_online": "你不能同时加入多个同步的服务器。" -} \ No newline at end of file +}