英文:
Why java class not do GET request
问题
I made java script, it save/load player inventory when he leave/join, but someting goes wrong(GET request dont send)
我制作了一个Java脚本,它在玩家加入/离开时保存/加载玩家的物品,但是出了一些问题(GET请求没有发送)
here is classes.
以下是类。
InventorySync:
import com.google.gson.Gson;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
import java.util.Arrays;
import java.util.Base64;
import java.util.UUID;
import InventoryGet.*;
public class InventorySync extends JavaPlugin implements Listener {
String saveInv = "正确的URL";
String loadInv = "正确的URL";
Gson gson = new Gson();
@EventHandler
public void onJoin(PlayerJoinEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
// InventoryGet.main(loadInv + "?username=" + uuid.toString());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
Object[] contents = Arrays.stream(player.getInventory().getContents()).toArray();
String inv = Base64.getEncoder().encodeToString(gson.toJson(contents).getBytes());
// InventoryGet.main(saveInv + "?username=" + uuid.toString() + "&inventory=" + inv);
}
}
InventoryGet:
package InventoryGet;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
public class InventoryGet {
public static String main(String urlString) throws IOException {
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
Scanner scanner = new Scanner(connection.getInputStream());
String response = scanner.useDelimiter("\\A").next();
scanner.close();
return response;
} else {
return "GET请求失败,响应代码为 " + responseCode;
}
} catch (Exception e) {
return "发生异常: " + e.getMessage();
}
}
}
The URL is correct.
URL是正确的。
For the PHP script:
Update inventory:
<?php
// 获取玩家昵称
// 检查用户名是否存在
if (!isset($_GET['username']))
{
die();
} else { // 用户名存在:
$username = $_GET['username'];
}
// 获取玩家的物品(如果存在)
if (!isset($_GET['inventory'])) {
die();
} else { // 从base64解码物品:
$inventory = base64_decode($_GET['inventory']);
} // 将物品保存到文件
file_put_contents('inventory/' . $username . '.inv', $inventory);
Get inventory:
<?php
header("content-type: application/json");
// 获取玩家昵称
// 检查用户名是否存在
if (!isset($_GET['username'])) {
die('[]');
} else { // 用户名存在
$username = $_GET['username'];
}
if (file_exists('inventory/' . $username . '.inv')) { // 如果存在,查找玩家的物品
echo file_get_contents('inventory/' . $username . '.inv');
} else { // 未找到玩家文件:
echo '[]';
}
当玩家从服务器断开连接时,服务器会保存他的物品,但服务器没有发送GET请求。
英文:
I made java script, it save/load player inventory when he leave/join, but someting goes wrong(GET request dont send)
here is classes.
InventorySync:
import com.google.gson.Gson;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
import java.util.Arrays;
import java.util.Base64;
import java.util.UUID;
import InventoryGet.*;
public class InventorySync extends JavaPlugin implements Listener {
String saveInv = "*correct url*";
String loadInv = "*correct url*";
Gson gson = new Gson();
@EventHandler
public void onJoin(PlayerJoinEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
//InventoryGet.main(loadInv + "?username=" + uuid.toString());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
Object[] contents = Arrays.stream(player.getInventory().getContents()).toArray();
String inv = Base64.getEncoder().encodeToString( gson.toJson(contents).getBytes() );
InventoryGet.main(saveInv + "?username=" + uuid.toString() + "&inventory=" + inv);
}
}
InventoryGet:
package InventoryGet;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
public class InventoryGet {
public static String main(String urlString) throws IOException {
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
Scanner scanner = new Scanner(connection.getInputStream());
String response = scanner.useDelimiter("\\A").next();
scanner.close();
return response;
} else {
return "GET request failed with response code " + responseCode;
}
} catch (Exception e) {
return "Exception occurred: " + e.getMessage();
}
}
}
The URL is correct.
For the PHP script:
Update inventory:
<?php
//Get player nickname
//check username for exist
if (!isset($_GET['username']))
{
die();
} else { //username exist:
$username = $_GET['username'];
}
//get player inventory(if exist)
if (!isset($_GET['inventory'])) {
die();
} else { //decode inventory from base64:
$inventory = base64_decode($_GET['inventory']);
} //save inventory to file
file_put_contents('inventory/' . $username . '.inv', $inventory);
Get inventory:
<?php
header("content-type: application/json");
//Get player nickname
//check username for exist
if (!isset($_GET['username'])) {
die('[]');
} else { // username exist
$username = $_GET['username'];
}
if (file_exists('inventory/' . $username . '.inv')) { //find player's inventory if exists
echo file_get_contents('inventory/' . $username . '.inv');
} else { //player file not found:
echo '[]';
}
When player disconnect from server, server save his inventory, but server not do a GET request
答案1
得分: 1
- 你在
JavaPlugin
类中,没有onEnable()
方法来注册监听器。所以,你应该添加以下代码:
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
- 我建议你创建一个新的监听器类,包含如下内容(省略了导入部分):
public class InventorySync extends JavaPlugin {
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(new ConnectionListener(), this);
}
}
public class ConnectionListener implements Listener {
String saveInv = "正确的URL";
String loadInv = "正确的URL";
Gson gson = new Gson();
@EventHandler
public void onJoin(PlayerJoinEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
//InventoryGet.main(loadInv + "?username=" + uuid.toString());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
Object[] contents = Arrays.stream(player.getInventory().getContents()).toArray();
String inv = Base64.getEncoder().encodeToString( gson.toJson(contents).getBytes() );
InventoryGet.main(saveInv + "?username=" + uuid.toString() + "&inventory=" + inv);
}
}
-
你不应该使用
GET
请求来更新数据,应该使用POST
方法。 -
你错误地使用了gson,根据Spigot API的要求,你应该使用
ItemStack#serialize
和ItemStack#deserialize
,如下所示:
@EventHandler
public void onJoin(PlayerJoinEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
String inv = main(loadInv + "?username=" + uuid.toString());
List<Map<String, Object>> list = gson.fromJson(inv, List.class);
list.stream().map(ItemStack::deserialize).forEach(it -> {
// 这里有物品
});
}
@EventHandler
public void onQuit(PlayerQuitEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
List<Map<String, Object>> contents = Arrays.stream(player.getInventory().getContents()).filter(Objects::nonNull).map(ItemStack::serialize).collect(Collectors.toList());
String inv = Base64.getEncoder().encodeToString(gson.toJson(contents).getBytes());
main(saveInv + "?username=" + uuid.toString() + "&inventory=" + inv);
}
我添加了filter(Objects::nonNull)
以防止空的物品槽。
英文:
You said it's full code, so there is multiple issues :
- You are in the
JavaPlugin
class, and there isn'tonEnable()
method that register listener. So, you should add:
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
- I suggest you to create a new class for listeners, to have (I omitted import):
public class InventorySync extends JavaPlugin {
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(new ConnectionListener(), this);
}
}
public class ConnectionListener implements Listener {
String saveInv = "*correct url*";
String loadInv = "*correct url*";
Gson gson = new Gson();
@EventHandler
public void onJoin(PlayerJoinEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
//InventoryGet.main(loadInv + "?username=" + uuid.toString());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
Object[] contents = Arrays.stream(player.getInventory().getContents()).toArray();
String inv = Base64.getEncoder().encodeToString( gson.toJson(contents).getBytes() );
InventoryGet.main(saveInv + "?username=" + uuid.toString() + "&inventory=" + inv);
}
}
-
You should not use
GET
request to update datas. The methodPOST
is here. -
You are wrongly using gson according to Spigot API. You should use
ItemStack#serialize
andItemStack#deserialize
, like that:
@EventHandler
public void onJoin(PlayerJoinEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
String inv = main(loadInv + "?username=" + uuid.toString());
List<Map<String, Object>> list = gson.fromJson(inv, List.class);
list.stream().map(ItemStack::deserialize).forEach(it -> {
// here you have items
});
}
@EventHandler
public void onQuit(PlayerQuitEvent event) throws IOException {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
List<Map<String, Object>> contents = Arrays.stream(player.getInventory().getContents()).filter(Objects::nonNull).map(ItemStack::serialize).collect(Collectors.toList());
String inv = Base64.getEncoder().encodeToString(gson.toJson(contents).getBytes());
main(saveInv + "?username=" + uuid.toString() + "&inventory=" + inv);
}
I added filter(Objects::nonNull)
to prevent empty slot
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论