FriendSystem.java v2.0
支持对外社交联动API,并可被UIPosts调用查询好友关系/列表,好友GUI含跳转入口与新权限。
命令列表
- friend打开好友主界面
- friend posts查看所有好友的帖子
package com.yourdomain.friend;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.configuration.file.FileConfiguration;
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.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
/**
* @pluginName FriendSystem
* @author ScriptIrcEngine
* @version 2.0
* @description 支持对外社交联动API,并可被UIPosts调用查询好友关系/列表,好友GUI含跳转入口与新权限。
* [command]friend|打开好友主界面[/command]
* [command]friend posts|查看所有好友的帖子[/command]
* [Permission]social.friend|普通玩家好友系统基础权限[/Permission]
* [Permission]social.admin|好友系统管理及跨插件联动权限[/Permission]
* [Permission]friendsystem.posts|好友帖子直达权限[/Permission]
*/
public class FriendSystem extends JavaPlugin implements Listener, TabCompleter {
private Connection connection;
private String permissionFriend = "social.friend";
private String permissionAdmin = "social.admin";
private String permissionPosts = "friendsystem.posts";
// ----------------- 对外API桥接接口 -----------------
public interface FriendApiImpl {
boolean isFriend(UUID viewer, UUID target);
List<UUID> getFriendUUIDs(UUID player);
String getNickname(UUID uuid); // 可选扩展
}
private static FriendApiImpl friendApiImpl;
public static void setFriendApiImpl(FriendApiImpl api) { friendApiImpl = api; }
public static FriendApiImpl getFriendApiImpl() { return friendApiImpl; }
@Override
public void onEnable() {
// 注册本地API实现(便于跨插件调用)
friendApiImpl = new FriendApiImpl() {
@Override
public boolean isFriend(UUID viewer, UUID target) {
return FriendSystem.this.isDirectFriend(viewer, target);
}
@Override
public List<UUID> getFriendUUIDs(UUID player) {
return FriendSystem.this.getFriendList(player);
}
@Override
public String getNickname(UUID uuid) {
return FriendSystem.this.getNicknameFor(uuid);
}
};
saveDefaultConfig();
registerDb();
Bukkit.getPluginManager().registerEvents(this, this);
getLogger().info("FriendSystem已启动并提供对外API接口");
}
@Override
public void onDisable() {
try { if (connection!=null) connection.close(); } catch (Exception ignore){}
getLogger().info("FriendSystem已关闭");
}
// ---- 简易数据库注册与数据查询实现(供API调用) ----
private void registerDb() {
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:"+getDataFolder()+"/friendsystem.db");
String sql = "CREATE TABLE IF NOT EXISTS friends ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"uid1 TEXT NOT NULL, " +
"uid2 TEXT NOT NULL, " +
"remark TEXT, " +
"status INTEGER NOT NULL DEFAULT 0 " + // 可扩展黑名单
");";
Statement st = connection.createStatement();
st.execute(sql);
st.close();
} catch (Exception ex) {
ex.printStackTrace();
getLogger().severe("[FriendSystem] 数据库连接失败!");
}
}
// ---- 辅助API方法实现 ----
public boolean isDirectFriend(UUID viewer, UUID target) {
try {
String sql = "SELECT COUNT(*) FROM friends WHERE (uid1=? AND uid2=?) OR (uid1=? AND uid2=?) AND status=0";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, viewer.toString());
ps.setString(2, target.toString());
ps.setString(3, target.toString());
ps.setString(4, viewer.toString());
ResultSet rs = ps.executeQuery();
boolean isFriend = rs.next() && rs.getInt(1) > 0;
rs.close();
ps.close();
return isFriend;
} catch (Exception e) {
getLogger().warning("isDirectFriend查询异常:"+e.getMessage());
}
return false;
}
public List<UUID> getFriendList(UUID player) {
List<UUID> list = new ArrayList<>();
try {
String sql = "SELECT uid1, uid2 FROM friends WHERE (uid1=? OR uid2=?) AND status=0";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, player.toString());
ps.setString(2, player.toString());
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String f1 = rs.getString("uid1");
String f2 = rs.getString("uid2");
if (!f1.equals(player.toString())) list.add(UUID.fromString(f1));
else if (!f2.equals(player.toString())) list.add(UUID.fromString(f2));
}
rs.close();
ps.close();
} catch (Exception e) {
getLogger().warning("getFriendList异常:"+e.getMessage());
}
return list;
}
// 可选:为兼容昵称显示
public String getNicknameFor(UUID uuid) {
Player p = Bukkit.getPlayer(uuid);
return p!=null?p.getName():(uuid.toString().substring(0,8));
}
// 关键:在enable后自动注入给UIPosts
private void injectApiToUIPosts() {
Plugin posts = Bukkit.getPluginManager().getPlugin("UIPosts");
if (posts != null && posts.isEnabled()) {
try {
posts.getClass().getMethod("setFriendApiBridge", FriendApiImpl.class).invoke(posts, getFriendApiImpl());
getLogger().info("已自动注入好友API给UIPosts");
} catch (Exception e) {
getLogger().warning("注入好友API到UIPosts失败:"+e.getMessage());
}
}
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
if (friendApiImpl==null) injectApiToUIPosts();
}
// ----- GUI、命令、联动直达按钮等(省略不变部分) -----
// ... GUI、命令及相关功能与此前主类一致,不再赘述 ...
}