来自 Bukkit 插件的 TCP 连接
TCP connection from Bukkit plugin
我正在尝试创建一个 bukkit 插件,它将连接到 tcp 服务器并在事件触发时发送消息。
我已经掌握了基础知识,但我遗漏了一些东西,而且我不明白从这里该何去何从。我可以看到该插件与服务器建立了连接,但随后抛出错误且未发送任何消息。
我想了解在事件发生时我是如何向 tcp 客户端发送字符串的。为了测试,我正在使用玩家移动事件。
启动时,我在 craftbukkit 服务器日志中看到以下内容:
Loading libraries, please wait...
[19:53:25 INFO]: Starting minecraft server version 1.7.10
[19:53:25 INFO]: Loading properties
[19:53:25 INFO]: Default game type: SURVIVAL
[19:53:25 INFO]: Generating keypair
[19:53:26 INFO]: Starting Minecraft server on *:25565
[19:53:26 INFO]: This server is running CraftBukkit version git-Bukkit-1.7.9-R0.2-20-g0b2ed13-b3108jnks (MC: 1.7.10) (Implementing API version 1.7.10-R0.1-SNAPSHOT)
[19:53:27 INFO]: [Compass] Loading Compass v0.1
[19:53:27 INFO]: Preparing level "world"
[19:53:27 INFO]: Preparing start region for level 0 (Seed: 7985848474339719790)
[19:53:27 WARN]: Could not get information about this CraftBukkit version; perhaps you are running a custom one?: FileNotFoundException
[19:53:28 INFO]: Preparing spawn area: 66%
[19:53:28 WARN]: Could not get latest artifact information: FileNotFoundException
[19:53:28 INFO]: Preparing start region for level 1 (Seed: 524789769407484853)
[19:53:29 INFO]: Preparing spawn area: 70%
[19:53:30 INFO]: Preparing start region for level 2 (Seed: 524789769407484853)
[19:53:30 INFO]: [Compass] Enabling Compass v0.1
[19:53:30 INFO]: [Compass] Start up.
[19:53:30 INFO]: [Compass] trying connect0
[19:53:30 INFO]: [Compass] getOutputStream()
[19:53:30 INFO]: [Compass] getInputStream()
[19:53:30 INFO]: Server permissions file permissions.yml is empty, ignoring it
[19:53:30 INFO]: Done (3.312s)! For help, type "help" or "?"
[19:54:25 INFO]: UUID of player MagicPixelPunk is 0322446d-6b92-4b63-af77-98d6739ec53b
[19:54:25 INFO]: MagicPixelPunk[/127.0.0.1:55376] logged in with entity id 206 at ([world] -164.16068813003193, 65.0, -141.0983355740641)
当我连接 minecraft 客户端并移动玩家时,我在 craftbukkit 服务器日志中看到以下错误:
21:52:01 INFO]: outToServer is null
21:52:01 INFO]: [CompassTask] writing to outToServer
21:52:01 INFO]: [CompassTask] Send failed: exception:
21:52:01 WARN]: java.lang.NullPointerException
21:52:01 WARN]: at compass.Compass.onMove(Compass.java:61)
javaclassCompass.java如下:
package compass;
import java.util.logging.Logger;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.CommandException;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import java.lang.Exception;
import java.lang.Error;
import java.io.*;
import java.net.*;
public class Compass extends JavaPlugin implements Listener{
public static Logger log = Logger.getLogger("Minecraft");
public DataOutputStream outToServer;
public void onEnable() {
log.info("[Compass] Start up.");
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
log.info("[Compass] trying connect0");
try{
Socket clientSocket = new Socket("localhost", 6789);
log.info("[Compass] getOutputStream()");
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
log.info("[Compass] getInputStream()");
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (Exception e){
log.info("[Compass] Send failed: Exception: ");
e.printStackTrace();
}
getServer().getPluginManager().registerEvents(this, this);
}
public void onReload() {
log.info("[Compass] Server reloaded.");
}
public void onDisable() {
log.info("[Compass] Server stopping.");
}
@EventHandler
public void onMove(PlayerMoveEvent event) {
try{
if (outToServer == null) {
log.info("outToServer is null");
}
log.info("[CompassTask] writing to outToServer");
outToServer.writeBytes("test"+"\n");
log.info(" [x] Sent '" + "test" + "'");
}
catch (Exception e){
log.info("[CompassTask] Send failed: exception:");
e.printStackTrace();
}
catch (Error e){
log.info("[CompassTask] Send failed: error:");
e.printStackTrace();
}
}
}
关于为什么当我尝试写入时 outToServer 为 null 的任何想法?
鉴于错误显示
[19:53:30 INFO]: [Compass] Enabling Compass v0.1
[19:53:30 INFO]: [Compass] Start up.
[19:53:30 INFO]: [Compass] trying connect0
[19:53:30 INFO]: [Compass] getOutputStream()
[19:53:30 INFO]: [Compass] getInputStream()
然后说
error: [Errno 10054] An existing connection was forcibly closed by the remote host
我要说你的错误在于 runnable.runTaskTimer(this, 20, 100);
所以很可能你没有给服务器足够的时间。
看来问题出在以下行:
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
我猜这是在创建一个局部变量,所以当我尝试在 onEnable() 之外使用它时 outToServer 为 null
我改为:
outToServer = new DataOutputStream(clientSocket.getOutputStream());
现在工作正常。
我正在尝试创建一个 bukkit 插件,它将连接到 tcp 服务器并在事件触发时发送消息。
我已经掌握了基础知识,但我遗漏了一些东西,而且我不明白从这里该何去何从。我可以看到该插件与服务器建立了连接,但随后抛出错误且未发送任何消息。
我想了解在事件发生时我是如何向 tcp 客户端发送字符串的。为了测试,我正在使用玩家移动事件。
启动时,我在 craftbukkit 服务器日志中看到以下内容:
Loading libraries, please wait...
[19:53:25 INFO]: Starting minecraft server version 1.7.10
[19:53:25 INFO]: Loading properties
[19:53:25 INFO]: Default game type: SURVIVAL
[19:53:25 INFO]: Generating keypair
[19:53:26 INFO]: Starting Minecraft server on *:25565
[19:53:26 INFO]: This server is running CraftBukkit version git-Bukkit-1.7.9-R0.2-20-g0b2ed13-b3108jnks (MC: 1.7.10) (Implementing API version 1.7.10-R0.1-SNAPSHOT)
[19:53:27 INFO]: [Compass] Loading Compass v0.1
[19:53:27 INFO]: Preparing level "world"
[19:53:27 INFO]: Preparing start region for level 0 (Seed: 7985848474339719790)
[19:53:27 WARN]: Could not get information about this CraftBukkit version; perhaps you are running a custom one?: FileNotFoundException
[19:53:28 INFO]: Preparing spawn area: 66%
[19:53:28 WARN]: Could not get latest artifact information: FileNotFoundException
[19:53:28 INFO]: Preparing start region for level 1 (Seed: 524789769407484853)
[19:53:29 INFO]: Preparing spawn area: 70%
[19:53:30 INFO]: Preparing start region for level 2 (Seed: 524789769407484853)
[19:53:30 INFO]: [Compass] Enabling Compass v0.1
[19:53:30 INFO]: [Compass] Start up.
[19:53:30 INFO]: [Compass] trying connect0
[19:53:30 INFO]: [Compass] getOutputStream()
[19:53:30 INFO]: [Compass] getInputStream()
[19:53:30 INFO]: Server permissions file permissions.yml is empty, ignoring it
[19:53:30 INFO]: Done (3.312s)! For help, type "help" or "?"
[19:54:25 INFO]: UUID of player MagicPixelPunk is 0322446d-6b92-4b63-af77-98d6739ec53b
[19:54:25 INFO]: MagicPixelPunk[/127.0.0.1:55376] logged in with entity id 206 at ([world] -164.16068813003193, 65.0, -141.0983355740641)
当我连接 minecraft 客户端并移动玩家时,我在 craftbukkit 服务器日志中看到以下错误:
21:52:01 INFO]: outToServer is null
21:52:01 INFO]: [CompassTask] writing to outToServer
21:52:01 INFO]: [CompassTask] Send failed: exception:
21:52:01 WARN]: java.lang.NullPointerException
21:52:01 WARN]: at compass.Compass.onMove(Compass.java:61)
javaclassCompass.java如下:
package compass;
import java.util.logging.Logger;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.CommandException;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import java.lang.Exception;
import java.lang.Error;
import java.io.*;
import java.net.*;
public class Compass extends JavaPlugin implements Listener{
public static Logger log = Logger.getLogger("Minecraft");
public DataOutputStream outToServer;
public void onEnable() {
log.info("[Compass] Start up.");
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
log.info("[Compass] trying connect0");
try{
Socket clientSocket = new Socket("localhost", 6789);
log.info("[Compass] getOutputStream()");
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
log.info("[Compass] getInputStream()");
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (Exception e){
log.info("[Compass] Send failed: Exception: ");
e.printStackTrace();
}
getServer().getPluginManager().registerEvents(this, this);
}
public void onReload() {
log.info("[Compass] Server reloaded.");
}
public void onDisable() {
log.info("[Compass] Server stopping.");
}
@EventHandler
public void onMove(PlayerMoveEvent event) {
try{
if (outToServer == null) {
log.info("outToServer is null");
}
log.info("[CompassTask] writing to outToServer");
outToServer.writeBytes("test"+"\n");
log.info(" [x] Sent '" + "test" + "'");
}
catch (Exception e){
log.info("[CompassTask] Send failed: exception:");
e.printStackTrace();
}
catch (Error e){
log.info("[CompassTask] Send failed: error:");
e.printStackTrace();
}
}
}
关于为什么当我尝试写入时 outToServer 为 null 的任何想法?
鉴于错误显示
[19:53:30 INFO]: [Compass] Enabling Compass v0.1
[19:53:30 INFO]: [Compass] Start up.
[19:53:30 INFO]: [Compass] trying connect0
[19:53:30 INFO]: [Compass] getOutputStream()
[19:53:30 INFO]: [Compass] getInputStream()
然后说
error: [Errno 10054] An existing connection was forcibly closed by the remote host
我要说你的错误在于 runnable.runTaskTimer(this, 20, 100);
所以很可能你没有给服务器足够的时间。
看来问题出在以下行:
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
我猜这是在创建一个局部变量,所以当我尝试在 onEnable() 之外使用它时 outToServer 为 null
我改为:
outToServer = new DataOutputStream(clientSocket.getOutputStream());
现在工作正常。