冷恋韩轩 发表于 2009-10-16 01:23:28

关于 "远程截取当前在线玩家屏幕图片" 插件的问题

本帖最后由 冷恋韩轩 于 2009-10-16 01:26 编辑

小弟在疾风的指示下, 发现了这个插件 cheaterSuspect   [   这个是直接在motd窗口上传 ]
                  
          在此付源码:源码在2、3楼
里面有许多配置文件,但是不知道怎么装. 请大虾指示...
      所有集成文件下载地址:

冷恋韩轩 发表于 2009-10-16 01:25:19

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <dbi>
#define PLUGIN "Cheater Suspect"
#define AUTHOR "tmen13 / Albernaz O Carniceiro Demoniaco"
#define VERSION "1.2"
#define DB_NAME "cheaterSuspect"
#define DB_TABLE_SUSPECTS "suspects"
#define ADMIN_FLAG ADMIN_BAN
#define MAP_MAX_LEN 33
#define PHOTO_ID_LEN 33
#define PHOTO_DATE_LEN 22
#define IP_LEN 16
#define OFFSET_TEAM 114
new const CFG_FILENAME[] = "cheaterSuspect.ini";
const CFG_MAX_PARAM_LEN = 50;
new CFG_SITE_URL;
new CFG_FILES_FILE;
new CFG_SUBMIT_FILE;
const CFG_FULL_URL_MAX_LEN = CFG_MAX_PARAM_LEN * 2;
new CFG_FILES_URL
new CFG_SUBMIT_URL
new MENU_TITLE_BASE[] = "Cheater Suspect Menu"
new MENU_EXIT_TEXT[] = "exit";
new MENU_PREVIOUSPAGE_TEXT[] = "previous page";
new MENU_NEXTPAGE_TEXT[] = "next page";
new MENU_BACK_TEXT[] = "back";
new MENU_ITEM_SUSPECT_PLAYER[]= "Suspect of player"
new MENU_ITEM_MANAGE_SUSPECTS[] = "Manage suspects"
new MENU_ITEM_SHOW_RECEIVED_FILES[] = "Show received files"
new ForwardClientDisconnect
new ForwardClientUserInfoChanged;
new HamHook:ForwardTraceAttack;
new HamHook:ForwardSpawn;
new bool:IsBlocked;
new bool:IsPendingSnapshot
new PendingSnapshot;
new Blockeds;
new SQL_ERROR_MSG
enum suspectLevel
{
NOT_SUSPECT,
SUSPECT_WITHOUT_SNAPSHOT,
SUSPECT_WITH_SNAPSHOT
}
new BUFFER_SUSPECT_ID
new BUFFER_STEAM_ID
enum BAN_TYPE
{
IP,
STEAMID,
STEAMID_AND_IP
}
new CvarBanType
handleConfigFile()
{
const configsDirLastIndex = 49;
new configsDir;

get_configsdir(configsDir,configsDirLastIndex);

const fileNameLastIndex = configsDirLastIndex + 15;
new fileName;

format(fileName,fileNameLastIndex,"%s/%s",configsDir,CFG_FILENAME);

if(file_exists(fileName))
{
new file = fopen(fileName,"r");

if(!feof(file))
   fgets (file,CFG_SITE_URL,CFG_MAX_PARAM_LEN-1);

if(!feof(file))
{
   fgets (file,CFG_FILES_FILE,CFG_MAX_PARAM_LEN-1);
   format(CFG_FILES_URL,CFG_FULL_URL_MAX_LEN-1,"%s%s",CFG_SITE_URL,CFG_FILES_FILE);
}

if(!feof(file))
{
   fgets (file,CFG_SUBMIT_FILE,CFG_MAX_PARAM_LEN-1);
   format(CFG_SUBMIT_URL,CFG_FULL_URL_MAX_LEN-1,"%s%s",CFG_SITE_URL,CFG_SUBMIT_FILE);
}
}
}
getRandomPhotoID(photoID)
{
new i;

for(i=0;i<PHOTO_ID_LEN-1;i++)
photoID = '0' + random(10)

photoID = 0;
}

Sql:sql_getConnection()
return dbi_connect("", "", "", DB_NAME , SQL_ERROR_MSG, 255);
sql_getSuspectIP(steamID,ip)
{
new Sql:connection = sql_getConnection();
new Result:result = dbi_query(connection,"SELECT ip FROM %s WHERE steamID='%s';",DB_TABLE_SUSPECTS,steamID);

if(result >= RESULT_OK)
{
dbi_field(result,1,ip,IP_LEN-1);

dbi_free_result(result);
}

dbi_close(connection);
}
sql_getSuspectInfo(steamID,map,photoDate,photoID,name)
{
new Sql:connection = sql_getConnection();
new Result:result = dbi_query(connection,"SELECT map,photoDate,photoID,name FROM %s WHERE steamID='%s';",DB_TABLE_SUSPECTS,steamID);

if(result >= RESULT_OK)
{
dbi_field(result,1,map,MAP_MAX_LEN-1);
dbi_field(result,2,photoDate,PHOTO_DATE_LEN-1);
dbi_field(result,3,photoID,PHOTO_ID_LEN-1);
dbi_field(result,4,name,31);

dbi_free_result(result);
}

dbi_close(connection);
}

sql_registerSuspect(id)
{
new name
new steamID
new ip

get_user_name(id,name,31);
get_user_authid(id,steamID,33);
get_user_ip(id,ip,IP_LEN-1);


new Sql:connection = sql_getConnection();

dbi_query(connection,"INSERT INTO %s (steamID,name,ip) VALUES('%s',^"%s^",'%s')",DB_TABLE_SUSPECTS,steamID,name,ip);

dbi_close(connection);
}
sql_unregisterSuspect(steamID)
{
new Sql:connection = sql_getConnection();
dbi_query(connection,"DELETE FROM %s WHERE steamID='%s';",DB_TABLE_SUSPECTS,steamID);
dbi_close(connection);
}
sql_addSuspectInfo(id,photoID,photoDate,ip)
{
new map
get_mapname(map,MAP_MAX_LEN-1);

new steamID
get_user_authid(id,steamID,33);

new Sql:connection = sql_getConnection();

dbi_query(connection,"UPDATE %s SET map='%s',photoID='%s',photoDate='%s',ip='%s' WHERE steamID='%s'",DB_TABLE_SUSPECTS,map,photoID,photoDate,ip,steamID);

dbi_close(connection);
}
suspectLevel:sql_getSuspectLevel(id)
{
new steamID
get_user_authid(id,steamID,33);

new Sql:connection = sql_getConnection();

new Result:result = dbi_query(connection,"SELECT photoID FROM %s WHERE steamID='%s'",DB_TABLE_SUSPECTS,steamID);

if(result >= RESULT_OK)
{
new photoID
dbi_field(result,1,photoID,PHOTO_ID_LEN-1);

dbi_free_result(result);

if(photoID)
   return SUSPECT_WITH_SNAPSHOT
else
   return SUSPECT_WITHOUT_SNAPSHOT
}

return NOT_SUSPECT;
}
transferToSpectator(id)
{
set_pdata_int(id,OFFSET_TEAM,3);

dllfunc(DLLFunc_ClientUserInfoChanged, id);

message_begin(MSG_ALL, get_user_msgid("TeamInfo"));
write_byte(id);
write_string("SPECTATOR");
message_end();
}
registerToSnapshot(id)
{
IsPendingSnapshot = true;
PendingSnapshot++
if(PendingSnapshot == 1)
{
ForwardTraceAttack = RegisterHam(Ham_TraceAttack,"player","playerTraceAttack");

checkRegFwdClientDisconnect()
}
}
unregisterToSnapshot(id)
{
IsPendingSnapshot = false;
PendingSnapshot--;

if(!PendingSnapshot)
{
DisableHamForward(ForwardTraceAttack);
ForwardTraceAttack = HamHook:0;

checkUnregFwdClientDisconnect();
}
}
block(id)
{
IsBlocked = true;
Blockeds++;

if(Blockeds == 1)
{
ForwardClientUserInfoChanged = register_forward(FM_ClientUserInfoChanged,"clientUserInfoChanged");
ForwardSpawn = RegisterHam(Ham_Spawn,"player","spawn");
   
checkRegFwdClientDisconnect();
}
}
unblock(id)
{
IsBlocked = false;
Blockeds--;

if(!Blockeds)
{
unregister_forward(FM_ClientUserInfoChanged,ForwardClientUserInfoChanged);
ForwardClientUserInfoChanged = 0;

DisableHamForward(ForwardSpawn);
ForwardSpawn = HamHook:0;

checkUnregFwdClientDisconnect();
}
}
public spawn(id)
{
if(IsBlocked)
{
new ret;
ExecuteForward(ForwardClientUserInfoChanged,ret,id,ret);
}
}
checkRegFwdClientDisconnect()
{
if(!ForwardClientDisconnect)
ForwardClientDisconnect = register_forward(FM_ClientDisconnect,"clientDisconnect");
}
checkUnregFwdClientDisconnect()
{
if(!PendingSnapshot && !Blockeds)
{
unregister_forward(FM_ClientDisconnect,ForwardClientDisconnect);
ForwardClientDisconnect = 0;
}
}
public clientDisconnect(id)
{
if(IsPendingSnapshot)
unregisterToSnapshot(id);

if(IsBlocked)
unblock(id);
}
public client_connect(id)
{
switch(sql_getSuspectLevel(id))
{
case SUSPECT_WITH_SNAPSHOT:
   block(id);

case SUSPECT_WITHOUT_SNAPSHOT:
   registerToSnapshot(id);
}
}
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_clcmd("cheaterSuspect","showMenuCheaterSuspect");

new cvarValueString

num_to_str(_:STEAMID_AND_IP,cvarValueString,1);

CvarBanType = register_cvar("cheaterSuspect_ban_type", cvarValueString);
}
public plugin_cfg()
{
handleConfigFile()
}
public clientUserInfoChanged(id)
{
if(IsBlocked)
{
showMotdSubmit(id);
transferToSpectator(id)
user_silentkill(id);   
}
}
public suspect(id)
{
sql_registerSuspect(id);
registerToSnapshot(id);

return PLUGIN_HANDLED;
}
public playerTraceAttack(attackedID, id, Float:damage, Float:direction, tracehandle, damagebits)
{
if(IsPendingSnapshot)
{
if(get_pdata_int(id,OFFSET_TEAM) != get_pdata_int(attackedID,OFFSET_TEAM))
{   
   unregisterToSnapshot(id);
   
   new photoID   
   getRandomPhotoID(photoID);
   
   new year,month,day,hour,minute,seconds
   
   date(year,month,day)
   time(hour,minute,seconds);
   
   new photoDate
   
   
   
   format(photoDate,PHOTO_DATE_LEN-1,"%d-%d-%d %d:%d:%d",year,month,day,hour,minute,seconds);
   
   new ip
   get_user_ip(id,ip,15);
   
   sql_addSuspectInfo(id,photoID,photoDate,ip);
   
   client_print(id,print_chat,"%s %s",photoID,photoDate);
   
   new params
   params = id;
   
   set_task(1.0,"taskTakeSnapshot",0,params,1);   
   
   block(id);
}
}
}
public taskTakeSnapshot(params[])
client_cmd(params,"snapshot");

public showMenuCheaterSuspect(id)
{
if(get_user_flags(id) & ADMIN_FLAG)
{
new menu = menu_create("","handleMenuCheaterSuspect");

menu_setprop(menu,MPROP_TITLE,MENU_TITLE_BASE);
menu_setprop(menu,MPROP_EXITNAME,MENU_EXIT_TEXT);

menu_additem(menu,MENU_ITEM_SUSPECT_PLAYER,"1");
menu_additem(menu,MENU_ITEM_MANAGE_SUSPECTS,"2");
menu_additem(menu,MENU_ITEM_SHOW_RECEIVED_FILES,"3");

menu_display(id,menu,0);
}

return PLUGIN_HANDLED;
}
public handleMenuCheaterSuspect(id , menu , item)
{
if( item < 0 )
{
menu_destroy(menu);
return PLUGIN_CONTINUE;
}

new access, callback;

new actionString;
menu_item_getinfo(menu,item,access, actionString,1,_,_, callback);
menu_destroy(menu);
new action = str_to_num(actionString);

switch(action)
{
case 1:
{
   showMenuSelPlayerToSuspect(id)
}
case 2:
{
   showMenuSelPlayerSuspected(id);
}
case 3:
{
   showMenuCheaterSuspect(id);
   motdShowFiles(id);
}
}

return PLUGIN_HANDLED;
}

冷恋韩轩 发表于 2009-10-16 01:25:46

public showMenuSelPlayerToSuspect(id)
{
        new menu = menu_create("","handleMenuSelPlayerToSuspect");
       
        menu_setprop(menu, MPROP_EXITNAME, MENU_EXIT_TEXT);
       
        menu_setprop(menu, MPROP_NEXTNAME, MENU_PREVIOUSPAGE_TEXT);
        menu_setprop(menu, MPROP_BACKNAME, MENU_NEXTPAGE_TEXT);
       
        new bool:playersToSuspect
       
        new Players
        new playerCount, i, playerID
        get_players(Players, playerCount, "")
        for (i=0; i<playerCount; i++)
        {
                playerID = Players
          
                if(is_user_connected(playerID) && !is_user_bot(playerID) && !IsBlocked && !IsPendingSnapshot)
                {       
                        playersToSuspect = true;
                       
                        new playerIDString;
                        num_to_str(playerID,playerIDString,2);
                       
                        new name;
                        get_user_name(playerID,name,32);
                       
                        menu_additem(menu, name, playerIDString);       
                }
        }
       
        const titleExtraLen = 36
        new titleExtra
       
        if(!playersToSuspect)
        {
                menu_additem(menu, MENU_BACK_TEXT, "0");       
               
                format(titleExtra,titleExtraLen-1,"%s","There aren't players to suspect of.")
        }
        else
        {
                format(titleExtra,titleExtraLen-1,"%s","Select a player to suspect of:")
        }
       
        const fullTitleLen = sizeof MENU_TITLE_BASE + 2 + titleExtraLen;
        new fullTitle
       
        format(fullTitle,fullTitleLen-1,"%s^n^n%s",MENU_TITLE_BASE,titleExtra);

        menu_setprop(menu,MPROP_TITLE,fullTitle);
       
       
        menu_display(id,menu,0);
       
        return PLUGIN_CONTINUE;
}
public handleMenuSelPlayerToSuspect(id , menu , item)
{
        if( item < 0 )
        {
                menu_destroy(menu);
                return PLUGIN_CONTINUE;
        }
       
        new access, callback;
       
        new actionString;               
        menu_item_getinfo(menu,item,access, actionString,2,_,_, callback);               
        menu_destroy(menu);
        new suspectID = str_to_num(actionString);       
       
        switch(suspectID)
        {
                case 0:
                        showMenuCheaterSuspect(id);
                default:
                {               
                        BUFFER_SUSPECT_ID = suspectID;
                       
                        showMenuConfirmPlayerSuspect(id);
                }
        }
       
        return PLUGIN_HANDLED;
}       

       
public showMenuConfirmPlayerSuspect(id)
{
        new suspectID = BUFFER_SUSPECT_ID;
       
        new name;
        get_user_name(suspectID,name,31);
       
        new menu = menu_create("","handleMenuConfirmPlayerSuspect");
               
        new titleExtra[] = "Confirm? (%s):"
       
        const fullTitleLen = sizeof MENU_TITLE_BASE + 2 + sizeof titleExtra + 32;
        new fullTitle
       
        format(fullTitle,fullTitleLen-1,"%s^n^n%s",MENU_TITLE_BASE,titleExtra);
        format(fullTitle,fullTitleLen-1,fullTitle,name);
               
        menu_setprop(menu,MPROP_TITLE,fullTitle);
        menu_setprop(menu, MPROP_EXITNAME, "sair");
       
        menu_additem(menu, "Yes", "1");       
        menu_additem(menu, "No", "2");       
               
        menu_display(id,menu,0);
       
        return PLUGIN_CONTINUE;
}
public handleMenuConfirmPlayerSuspect(id , menu , item)
{
        if( item < 0 )
        {
                return PLUGIN_CONTINUE;
        }
       
        new access, callback;
       
        new actionString;               
        menu_item_getinfo(menu,item,access, actionString,1,_,_, callback);               
        new action = str_to_num(actionString);       
       
        switch(action)
        {
                case 0:
                {
                        showMenuCheaterSuspect(id);
                }
                case 1:
                {
                        new suspectID = BUFFER_SUSPECT_ID
                       
                        suspect(suspectID);
                       
                        new name
                        get_user_name(suspectID,name,31)
                       
                        client_print(id,print_chat,"Player ^"%s^" is now on the suspected list",name);
                       
                }
               
        }
       
        return PLUGIN_HANDLED;
}       

public motdShowFiles(id)
{
        new motd[] = "<iframe style='position:absolute;left:0px;top:0px;border-style:none;width:105%%;height:110%%' src='%s'>";
       
        const FULL_MOTD_LEN = sizeof(motd) + sizeof(CFG_FILES_URL);
        new fullMotd
       
        format(fullMotd,FULL_MOTD_LEN-1,motd,CFG_FILES_URL);
       
        show_motd(id,fullMotd);
       
}

public showMotdSubmit(id)
{       
        new motd[] = "<iframe style='position:absolute;left:0px;top:0px;border-style:none;width:105%%;height:110%%' src='%s'>"
        new linkVars[] = "?steamID=%s&map=%s&photoDate=%s&photoID=%s&name=%s";
       
        const linkLen = sizeof(CFG_SUBMIT_URL) + sizeof(linkVars) + 34 + MAP_MAX_LEN + PHOTO_DATE_LEN + PHOTO_ID_LEN;
        const motdFullLen = sizeof(motd) + linkLen
       
        new link
        new motdFull;
       
        new steamID;
        get_user_authid(id,steamID,33);
       
        new photoID
        new photoDate
        new map
        new name
               
        sql_getSuspectInfo(steamID,map,photoDate,photoID,name);       
               
        format(link,linkLen-1,"%s%s",CFG_SUBMIT_URL,linkVars);
        format(link,linkLen-1,link,steamID,map,photoDate,photoID,name);
       
        format(motdFull,motdFullLen-1,motd,link);
       
        show_motd(id,motdFull);
}

public showMenuSelPlayerSuspected(id)
{
        new menu = menu_create("","handleMenuSelPlayerSuspected");
       
        menu_setprop(menu, MPROP_EXITNAME, MENU_EXIT_TEXT);
        menu_setprop(menu, MPROP_NEXTNAME, MENU_NEXTPAGE_TEXT);
        menu_setprop(menu, MPROP_BACKNAME, MENU_PREVIOUSPAGE_TEXT);
       
        new Sql:connection = sql_getConnection()
       
        new Result:result = dbi_query(connection,"SELECT name,steamID FROM %s ORDER BY photoDate DESC;",DB_TABLE_SUSPECTS);
       
        const extraTitleLen = 30
        new extraTitle
       
        if(result >= RESULT_OK)
        {
                format(extraTitle,extraTitleLen-1,"%s","Choose a suspected player:");
               
                const labelLen = 32 + 3 + 34
                new label
               
                new name;
                new steamID;
               
                while(dbi_nextrow(result))
                {
                        dbi_field(result,1,name,31);
                        dbi_field(result,2,steamID,33);
                       
                        format(label,labelLen-1,"%s - %s",name,steamID);
                       
                        menu_additem(menu,label,steamID);
                }
        }
        else
        {
                format(extraTitle,extraTitleLen-1,"%s","There aren't suspects");
               
                menu_additem(menu,MENU_BACK_TEXT,"0");
        }
       
        const FULL_TITLE_LEN = sizeof(MENU_TITLE_BASE) + 2 + sizeof(extraTitle) + 1;
        new fullTitle;
       
        format(fullTitle,FULL_TITLE_LEN-1,"%s^n^n%s^n",MENU_TITLE_BASE,extraTitle);
       
        menu_setprop(menu,MPROP_TITLE,fullTitle);
       
        dbi_close(connection);
       
        menu_display(id,menu,0);
       
        return PLUGIN_CONTINUE;
}
public handleMenuSelPlayerSuspected(id , menu , item)
{
        if( item < 0 )
        {
                menu_destroy(menu);
                return PLUGIN_CONTINUE;
        }
       
        new access, callback;
       
        new actionString;               
        menu_item_getinfo(menu,item,access, actionString,33,_,_, callback);               
        menu_destroy(menu);
       
        if(actionString == 'S')
        {
                BUFFER_STEAM_ID = actionString;
                showMenuSuspectedPlayerActs(id);
        }
        else
        {
                showMenuCheaterSuspect(id);
        }
       
       
        return PLUGIN_HANDLED;
}
public showMenuSuspectedPlayerActs(id)
{
        new menu = menu_create("","handleMenuSuspectedPlayerActs");
       
        new titleExtra[] = "Manage suspect:"
       
        const titleLen = sizeof MENU_TITLE_BASE + 2 + sizeof titleExtra;
        new title
       
        format(title,titleLen-1,"%s^n^n%s",MENU_TITLE_BASE,titleExtra);
       
        menu_setprop(menu,MPROP_TITLE,title);
        menu_setprop(menu, MPROP_EXITNAME, MENU_EXIT_TEXT);
       
        menu_additem(menu,"ban","1");
        menu_additem(menu,"clean","2");
       
        menu_display(id,menu,0);
       
        return PLUGIN_CONTINUE;
}

getID(steamID)
{
        new steamIDCompare
       
        new Players
        new playerCount, i, id
        get_players(Players, playerCount, "")
        for (i=0; i<playerCount; i++)
        {
                id = Players

                if(is_user_connected(id))
                {
                        get_user_authid(id,steamIDCompare,33);
                       
                        if(!strcmp(steamID,steamIDCompare))
                                return id;
                }
        }
       
        return 0;
}

public handleMenuSuspectedPlayerActs(id , menu , item)
{
        if( item < 0 )
        {
                return PLUGIN_CONTINUE;
        }
       
        new access, callback;
       
        new actionString;               
        menu_item_getinfo(menu,item,access, actionString,1,_,_, callback);               
        new action = str_to_num(actionString);       
       
        new steamID;
        format(steamID,33,BUFFER_STEAM_ID);
       
        new suspectID = getID(steamID);
       
        switch(action)
        {
                case 1:
                {
                        new BAN_TYPE:ban_type = BAN_TYPE:clamp(get_pcvar_num(CvarBanType),0,_:BAN_TYPE-1);
                       
                        if(ban_type == STEAMID)
                        {
                                server_cmd("amx_addban ^"%s^" 0",steamID);
                        }
                        else
                        {
                                new ip;
                                sql_getSuspectIP(steamID,ip);
                               
                                if(ban_type == IP)
                                {
                                        server_cmd("amx_addban ^"%s^" 0",ip);
                               
                                }
                                else if(ban_type == STEAMID_AND_IP)
                                {
                                        server_cmd("amx_addban ^"%s^" 0",steamID);
                                        server_cmd("amx_addban ^"%s^" 0",ip);
                                }
                        }

                        if(suspectID)
                                server_cmd("kick ^"%d^"",get_user_userid(suspectID));
                       
                        client_print(id,print_chat,"Player banned");
                }
                case 2:
                {
                        if(suspectID)
                        {
                                if(IsBlocked)
                                        unblock(id);
                               
                                if(IsPendingSnapshot)
                                        unregisterToSnapshot(id)
                        }
                       
                        client_print(id,print_chat,"Player cleaned");
                }
        }
       
        sql_unregisterSuspect(steamID);
       
        return PLUGIN_HANDLED;
}

cityhonghu 发表于 2009-10-16 08:18:42

即使截了图,也需要客户端手动上传图片。
对于图片的确定,图片的上传,玩家是否愿意上传都是个问题。
单凭插件要做到自动上传,听说不可能。况且这种方式图片的容量有好几兆,对网络负担也是个问题。
只好在等sXe出截图功能。

那小子真帅 发表于 2009-10-16 08:47:42

KP的截图功能很不错

冷恋韩轩 发表于 2009-10-16 09:46:52

4# cityhonghu


貌似Sorpack可以噢。 是motd式上传。很强大蛤。链接:http://www.sorpack.com/dispbbs.asp?boardID=38&ID=69860&page=1

cityhonghu 发表于 2009-10-16 11:00:51

sac 不是单凭插件。是server-client方式。
问一下,sac提供服务端吗?在哪里可以下载?

wk703 发表于 2011-8-5 08:43:46

在哪里可以下载

ActIvE 发表于 2011-8-5 19:41:25

上传按钮可以试试用Javascript实现鼠标划过事件实现上传?

yoop 发表于 2011-11-7 13:24:17

学习下!!!!!!!!!!!!!
页: [1]
查看完整版本: 关于 "远程截取当前在线玩家屏幕图片" 插件的问题