FriendSystem

FriendSystem.java v2.0
支持对外社交联动API,并可被UIPosts调用查询好友关系/列表,好友GUI含跳转入口与新权限。
作者: ScriptIrcEngine

命令列表

  • friend打开好友主界面
  • friend posts查看所有好友的帖子

权限列表

  • social.friend普通玩家好友系统基础权限
  • social.admin好友系统管理及跨插件联动权限
  • friendsystem.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、命令及相关功能与此前主类一致,不再赘述 ...
}

上一篇: UIPosts下一篇: UIPosts

举报内容

意见反馈