为什么Java类不执行GET请求?

huangapple go评论71阅读模式
英文:

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 = &quot;*correct url*&quot;;
    String loadInv = &quot;*correct url*&quot;;
    Gson gson = new Gson();
    @EventHandler
    public void onJoin(PlayerJoinEvent event) throws IOException {
        Player player = event.getPlayer();
        UUID uuid = player.getUniqueId();
        //InventoryGet.main(loadInv + &quot;?username=&quot; + 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 + &quot;?username=&quot; + uuid.toString() + &quot;&amp;inventory=&quot; + 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(&quot;GET&quot;);

            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                Scanner scanner = new Scanner(connection.getInputStream());
                String response = scanner.useDelimiter(&quot;\\A&quot;).next();
                scanner.close();
                return response;
            } else {
                return &quot;GET request failed with response code &quot; + responseCode;
            }
        } catch (Exception e) {
            return &quot;Exception occurred: &quot; + e.getMessage();
        }
    }
}

The URL is correct.

For the PHP script:

Update inventory:

&lt;?php
//Get player nickname
//check username for exist
if (!isset($_GET[&#39;username&#39;]))
{
    die();
} else { //username exist:
    $username = $_GET[&#39;username&#39;];
}
//get player inventory(if exist)
if (!isset($_GET[&#39;inventory&#39;])) {
    die();
} else { //decode inventory from base64:
    $inventory = base64_decode($_GET[&#39;inventory&#39;]);
} //save inventory to file
file_put_contents(&#39;inventory/&#39; . $username . &#39;.inv&#39;, $inventory);

Get inventory:

&lt;?php
header(&quot;content-type: application/json&quot;);
//Get player nickname
//check username for exist
if (!isset($_GET[&#39;username&#39;])) {
    die(&#39;[]&#39;);
} else { // username exist
    $username = $_GET[&#39;username&#39;];
} 
if (file_exists(&#39;inventory/&#39; . $username . &#39;.inv&#39;)) { //find player&#39;s inventory if exists
    echo file_get_contents(&#39;inventory/&#39; . $username . &#39;.inv&#39;);
} else { //player file not found:
   echo &#39;[]&#39;;
}

When player disconnect from server, server save his inventory, but server not do a GET request

答案1

得分: 1

  1. 你在JavaPlugin类中,没有onEnable()方法来注册监听器。所以,你应该添加以下代码:
@Override
public void onEnable() {
   getServer().getPluginManager().registerEvents(this, this);
}
  1. 我建议你创建一个新的监听器类,包含如下内容(省略了导入部分):
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() + "&amp;inventory=" + inv);
   }
}
  1. 你不应该使用GET请求来更新数据,应该使用POST方法。

  2. 你错误地使用了gson,根据Spigot API的要求,你应该使用ItemStack#serializeItemStack#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() + "&amp;inventory=" + inv);
}

我添加了filter(Objects::nonNull)以防止空的物品槽。

英文:

You said it's full code, so there is multiple issues :

  1. You are in the JavaPlugin class, and there isn't onEnable() method that register listener. So, you should add:
@Override
public void onEnable() {
   getServer().getPluginManager().registerEvents(this, this);
}
  1. 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 = &quot;*correct url*&quot;;
   String loadInv = &quot;*correct url*&quot;;
   Gson gson = new Gson();
   @EventHandler
   public void onJoin(PlayerJoinEvent event) throws IOException {
        Player player = event.getPlayer();
        UUID uuid = player.getUniqueId();
        //InventoryGet.main(loadInv + &quot;?username=&quot; + 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 + &quot;?username=&quot; + uuid.toString() + &quot;&amp;inventory=&quot; + inv);
   }
}
  1. You should not use GET request to update datas. The method POST is here.

  2. You are wrongly using gson according to Spigot API. You should use ItemStack#serialize and ItemStack#deserialize, like that:

@EventHandler
public void onJoin(PlayerJoinEvent event) throws IOException {
	Player player = event.getPlayer();
	UUID uuid = player.getUniqueId();
	String inv = main(loadInv + &quot;?username=&quot; + uuid.toString());
	List&lt;Map&lt;String, Object&gt;&gt; list = gson.fromJson(inv, List.class);
	list.stream().map(ItemStack::deserialize).forEach(it -&gt; {
         // here you have items
	});
}

@EventHandler
public void onQuit(PlayerQuitEvent event) throws IOException {
	Player player = event.getPlayer();
	UUID uuid = player.getUniqueId();
	List&lt;Map&lt;String, Object&gt;&gt; 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 + &quot;?username=&quot; + uuid.toString() + &quot;&amp;inventory=&quot; + inv);
}

I added filter(Objects::nonNull) to prevent empty slot

huangapple
  • 本文由 发表于 2023年2月16日 15:38:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75469118.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定