廣告廣告
  加入我的最愛 設為首頁 風格修改
首頁 首尾
 手機版   訂閱   地圖  簡體 
您是第 1478 個閱讀者
 
發表文章 發表投票 回覆文章
  可列印版   加為IE收藏   收藏主題   上一主題 | 下一主題   
wangningyu
個人文章 個人相簿 個人日記 個人地圖
路人甲
級別: 路人甲 該用戶目前不上站
推文 x2 鮮花 x1
分享: 轉寄此文章 Facebook Plurk Twitter 版主評分版主評分 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片
推文 x0
[插件] [源码] 配套VGStats排名系统的傻瓜式注册+登录插件VSLogin

圖 1.



【插件资讯】

插件来源:原创
使用指令:VSLogin
安装路径:cstrike\addons\amxmodx\modules

【插件介绍】

可以在任何STEAM或非STEAM均可注册登录,需要管理在MySQL后台修改中文名和权限字母代码都是很多年前的由Baby大佬初版编写,后续我改得比较乱,如果你能改得动的就自己改吧!

这个插件源码是配套VGStats排名系统中的VSLogin使用
https://bbs-mychat.com/reads.php?tid=1080183

预览效果:


















这个插件配合VGStats可以显示当前玩家所持有的武器独立数据,效果如下:



完整插件源码如下:

VSLogin.sma
複製程式
#pragma dynamic 32768


#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <sqlx>
#include <hamsandwich>
#include <fakemeta>
#include <engine>
#include <fun>


//#include "VGuard2022/VGuard.inc"


#define PLUGIN  "Login system"
#define VERSION "3.05"
#define AUTHOR  "Koma & baby"


// 调试模式
#define DEBUG  0


// 服务器名
#define SERVER_NAME "VGStats"


// 用户表名
#define SQL_TABLE_REG_INFO "mt_reg"


// 管理日志
#define SQL_TABLE_LOG_ADMIN "mt_adminlog"


// 是否启用正版注册登录
#define OPEN_STEAM 1


#if OPEN_STEAM
// 正版用户
// 输入密码时限(秒)
#define COUNT_DOWN_FROM  15


// 最大重试次数
#define MAX_LOGIN_ATTEMPT 3


// 最小密码长度
#define MIN_PW_LEN  6


// 最大密码长度
#define MAX_PW_LEN  20
#endif // OPEN_STEAM


// 最大签名长度
#define MAX_SG_LEN 128


// 最大名子长度
#define MAX_NAME_LEN 33


// 最大VIP时间
#define MAX_EXP_LEN 33


// 试图建立表格(初次使用请设为1,表格建立以后为0)
#define MYSQL_CHECK  0


// 年费VIP标识
#define VIP_YEAR_FLAGS FLAG_CASE_SENSITIVE


// 未注册玩家是否加前缀ERR
#define WITH_UNREG_PREFIX  0


// 已开启无限金钱插件?
// 0 - 否 1 - 是
#define UNLIMITED_MONEY 1
#if UNLIMITED_MONEY
 #include <unlimited_money>
#endif


// 出现异常时的名字格式
#define ERR_NAME "[ERR#%d]%s"


// 关键词
#define ERR_NAME_KEYWORD "ERR#"


#define UNREG_PREFIX "[VGuard] "


new const MSG_ERRORS[][] =
{
 "未知登录错误!",
 "未使用VGuard反作弊!",
 "VGuard反作弊版本太低!",
 "检测到账号或密码错误!^n如果非本人注册请重新改名进服"
}


// 定时器类型
#define TASK_ID_MSG 222
#define TASK_ID_QSTATUS 333
#define TASK_ID_ERRMSG 555
#define TASK_ID_LOGIN 666
#define TASK_ID_CHECKLOGIN 777
#define TASK_ID_KICK 888
#define TASK_CHECK_QSTATUS 999


// 权限类型
#define ACC_VIP1  ADMIN_LEVEL_D // VIP p
#define ACC_VIP2  ADMIN_LEVEL_B // 超级VIP n
#define ACC_MM  ADMIN_LEVEL_C // MM高管 o
#define ACC_VIP3  ADMIN_LEVEL_A // 管理员 m
#define ACC_ADMIN ADMIN_RCON // 超级管理员 l


#define is_player(%1) (1<=%1<=32)


// 客户端错误类型
enum _:UserError
{
 MT_ERR_UNKNOW = 0, // 未知
 MT_ERR_NOVG, // 未使用VG
 MT_ERR_OLDVG, // VG版本太旧
 MT_ERR_PASS, // 密码错误
}


// VIP类型
enum _:UserType
{
 MT_UNKNOW = 0, // 未检查
 MT_UNREG, // 未注册 z
 MT_NONSTEAM, // 会员 z
}


enum _:UserData
{
 PlayerType,
 Name[MAX_NAME_LEN], // 英文名
 VGName[MAX_NAME_LEN], // 英文名
 ChsName[MAX_NAME_LEN], // 中文名
 AuthSQL[MAX_NAME_LEN], // 原始MD5密码
 VipDate[MAX_EXP_LEN], // VIP期限
 RegDate[MAX_EXP_LEN], // 注册时间
 Signature[MAX_SG_LEN], // 个性签名
 PW[MAX_NAME_LEN], // 输入的密码
 AuthCodeNow[MAX_NAME_LEN], // cmdauth
 AccessStr[MAX_NAME_LEN], // 权限字母
 AccessInt, // 权限数字
 QQ[MAX_NAME_LEN], // QQ
 Email[MAX_NAME_LEN], // Email
 Hardware[MAX_NAME_LEN], // 机器码
 ClientVerion, // 客户端版本
 EngineVersion, // 引擎版本
 Index, // 数字编号
 Exp // 经验值
}


enum bool:UserInfo
{
 VGuard, // 是否使用反作弊
 Entering_pw, // 正在输入密码
 Steam, // 是否为正版玩家
 Querying, // 是否正在查询
 Data_not_found, // 未注册
 Login, // 是否登录成功
 CheckOver, // 是否检查过
 Put_in_server, // 是否已经进服
 Joined_team, // 是否已经加入队伍
 Ignore_name_change, // 是否忽略改名将强制锁定
 ChangeChsName, // 是否第一次改名
 Err_prefix, // 是否包含ERR
 FindUser, // 是否查找过
 AccessUser, // 是否标记权限
}


#if OPEN_STEAM
new g_countdown[33]
new g_attempts[33]
new const NUM_1[1] = {'1'}
#endif // OPEN_STEAM


new g_UserData[33][UserData]
new bool:g_bUserInfo[33][UserInfo]


// 修复SQL换图时native error bug
new bool:g_mapchange_started


// 玩家级别
new const member[][]  = {"巡逻战警", "未注册", "会员"}
    
new const DIGIT_TO_CHAR[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
new const DAYS_IN_MONTH[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // 偷懒, 无视2月29日


new g_show_errmsg[33], g_errcode[33]
new p_default_access
new g_forward


new g_maxplayers
new g_msg_index[33]
new g_msg_type[33]


new g_str_date[32]
new g_valid_day[9]
new g_valid_day2[9]
new g_year, g_month, g_day


new g_log_Error[256]
new g_log_Login[256]
new g_log_Shop[256]


new pc_vg_kick
new pc_sql_host, pc_sql_user, pc_sql_pass, pc_sql_db
new pc_log_srv
new Handle:g_sql_tuple


new g_bLoginPacketCnt[33]
new Float:g_bLoginLog[33]








#define XO_PLAYER 5
#define m_iMenuCode 205
#define cs_get_user_menu(%0) get_pdata_int(%0, m_iMenuCode, XO_PLAYER)
#define cs_set_user_menu(%0,%1) set_pdata_int(%0, m_iMenuCode, %1, XO_PLAYER)


stock bb_menu_display(id, menu, page=0)
{
 cs_set_user_menu(id, 0)
 menu_display(id, menu, page)
}


stock user_kick(id, const reason[])
{
 server_cmd("kick #%d ^"** %s **^"", get_user_userid(id), reason)
}


stock client_color(receiver, sender, const message[], {Float,Sql,Result,_}:...)
{
 if (!sender || 1 <= receiver <= 32 && !is_user_connected(receiver))
 {
 return 0
 }
 
 static msg[190]
 vformat(msg, 189, message, 4)
 message_begin(receiver ? MSG_ONE_UNRELIABLE : MSG_ALL, get_user_msgid("SayText"), {0, 0, 0}, receiver)
 write_byte(sender)
 write_string(msg)
 message_end()
 
 return 1
}


public data_clear(id, bConnect)
{
 if(!is_player(id))
 return
 
 new szEmptyString[MAX_NAME_LEN]
 new szEmptyDate[MAX_EXP_LEN]
 new szEmptySign[MAX_SG_LEN]
 
 #if OPEN_STEAM
 g_countdown[id] = 0;
 #endif
 
 g_show_errmsg[id] = 0;
 g_errcode[id] = 0;


 if(bConnect)
 g_UserData[id][PlayerType] = MT_UNKNOW; // VIP类型


 g_UserData[id][Name]  = szEmptyString; // 英文名
 g_UserData[id][ChsName]  = szEmptyString; // 中文名
 g_UserData[id][AuthSQL]  = szEmptyString; // 原始MD5密码
 g_UserData[id][VipDate]  = szEmptyDate; // VIP期限
 g_UserData[id][RegDate]  = szEmptyDate; // 注册时间
 g_UserData[id][Signature]  = szEmptySign; // 个性签名
 g_UserData[id][AuthCodeNow]  = szEmptyDate; // cmdauth
 g_UserData[id][AccessStr]  = szEmptyDate; // 权限字母
 g_UserData[id][AccessInt]  = 0; // 权限数字
 g_UserData[id][QQ] = szEmptyDate; // QQ
 g_UserData[id][Email]  = szEmptyDate; // Email
 g_UserData[id][Hardware]  = szEmptyDate; // 机器码
 g_UserData[id][ClientVerion]   = 0; // 客户端版本
 g_UserData[id][EngineVersion]  = 0; // 引擎版本
 g_UserData[id][Index]  = 0; // 数字编号
 g_UserData[id][Exp]  = 0; // 经验值
 
 g_bUserInfo[id][VGuard]  = false; // 是否使用反作弊
 g_bUserInfo[id][Entering_pw] = false; // 是否正在输入密码
 g_bUserInfo[id][Steam]  = false; // 是否为正版玩家
 g_bUserInfo[id][Querying]  = false; // 是否正在查询
 g_bUserInfo[id][Data_not_found] = false; // 未注册
 g_bUserInfo[id][Login]  = false; // 是否登录成功
 g_bUserInfo[id][CheckOver]  = false; // 是否检查过
 g_bUserInfo[id][Put_in_server]  = false; // 是否已经进服
 g_bUserInfo[id][Joined_team]  = false; // 是否已经加入队伍
 g_bUserInfo[id][Ignore_name_change] = false; // 是否忽略改名将强制锁定
 g_bUserInfo[id][ChangeChsName]  = false; // 是否第一次改名
 g_bUserInfo[id][Err_prefix]  = false; // 是否包含ERR
 g_bUserInfo[id][FindUser] = false; // 是否查询过数据库
 g_bUserInfo[id][AccessUser] = false; // 是否标记过权限
 g_bLoginPacketCnt[id] = 0;
 g_bLoginLog[id] = 0.00
}


stock error_log(const message[], {Float,Sql,Result,_}:...)
{
 static msg[192]
 vformat(msg, 191, message, 2)
 if(!g_mapchange_started)
 log_to_file(g_log_Error, msg)
}


stock login_log(const message[], {Float,Sql,Result,_}:...)
{
 static msg[192]
 vformat(msg, 191, message, 2)
 if(!g_mapchange_started)
 log_to_file(g_log_Login, msg)
}


stock shop_log(const message[], {Float,Sql,Result,_}:...)
{
 static msg[192]
 vformat(msg, 191, message, 2)
 if(!g_mapchange_started)
 log_to_file(g_log_Shop, msg)
}


stock remove_prefixes(name[])
{
 new bool:change_name
 if (containi(name, "[NO-sXe-I]") != -1)
 {
 replace(name, 31, "[NO-sXe-I]", "")
 change_name = true
 }
 
#if WITH_UNREG_PREFIX
 if (contain(name, UNREG_PREFIX) != -1)
 {
 replace(name, 31, UNREG_PREFIX, "")
 change_name = true
 }
#endif
 return change_name
}




stock check_date()
{
 static Float:time_prev_change
 static Float:gametime
 gametime = get_gametime()


 if (time_prev_change < 0.001 || gametime - time_prev_change > 3600.0) // plugin init || >1 hour passed since last change 
 {
 new hour, minute, second
 time(hour, minute, second)
 new year, month, day
 date(year, month, day)
 get_strdate(g_valid_day, year, month, day)
 if (hour == 0)
 {
 get_previous_day(g_valid_day2, year, month, day)
 }
 else if (hour == 23)
 {
 get_next_day(g_valid_day2, year, month, day)
 }
 time_prev_change = gametime
 }
 
 #if DEBUG
 //server_print("gametime>>%f ", gametime)
 #endif
}


stock get_user_real_index(uid)
{
 for(new i=1; i<g_maxplayers; i++)
 {
 if(!is_user_connected(i))
 continue;
 
 if(uid == get_user_userid(i))
 return i;
 }
 
 return 0;
}




// 是否要正版注册和登录
#if OPEN_STEAM


stock is_steam(id)
{
 /*new sid[64]
 
 if(!is_player(id))
 return false;
 
 if(is_user_bot(id))
 return false;
 
 get_user_authid(id, sid, 63)
 client_print(id, print_chat, "steam id: %s", sid)
 if (containi(sid, "STEAM_ID_") != -1)
 return false;
 
 if (containi(sid, "VALVE_ID_") != -1)
 return false;
 
 if (containi(sid, "STEAM_") != -1)
 return true;
 
 return false;*/
 
 if(!is_player(id))
 return false;
 
 if(is_user_bot(id))
 return false;
 
 return true
}


stock is_utf8_name(const name[])
{
 new i, v
 for (i = 0; i < 32; i++)
 {
 v = name[i]
 if (v == 0)
 {
 break
 }
 else if (!(0 < v < 128))
 {
 return 1
 }
 }
 return 0
}


public cmd_reg_enter_password(id)
{
 if (!g_bUserInfo[id][Entering_pw])
 {
 return
 }
 static password[MAX_PW_LEN + 5]
 read_args(password, MAX_PW_LEN + 4)
 remove_quotes(password)
 if (!(MIN_PW_LEN <= strlen(password) <= MAX_PW_LEN))
 {
 client_color(id, id, "^x01[^x03%s^x01] ^x04密码长度必须在 %d - %d 之间", SERVER_NAME, MIN_PW_LEN, MAX_PW_LEN)
 client_cmd(id, "messagemode reg_enter_password")
 }
 else
 {
 copy(g_UserData[id][PW], MAX_PW_LEN, password)
 client_cmd(id, "messagemode reg_enter_password_again")
 client_color(id, id, "^x01[^x03%s^x01] ^x04请再次输入密码", SERVER_NAME)
 }
}
public cmd_reg_enter_password_again(id)
{
 if (!g_bUserInfo[id][Entering_pw])
 {
 return
 }
 static password[MAX_PW_LEN + 5]
 static md5_password[34]
 read_args(password, MAX_PW_LEN + 4)
 remove_quotes(password)
 if (equal(g_UserData[id][PW], password))
 {
 md5(password, md5_password)
 user_register(id, md5_password)
 g_bUserInfo[id][Entering_pw] = false
 }
 else
 {
 client_color(id, id, "^x01[^x03%s^x01] ^x03两次输入的密码不一致,请重新输入.", SERVER_NAME)
 client_cmd(id, "messagemode reg_enter_password")
 }
}
public cmd_enter_password(id)
{
 if (!g_bUserInfo[id][Entering_pw])
 {
 return
 }
 static password[MAX_PW_LEN + 3]
 read_args(password, MAX_PW_LEN + 2)
 remove_quotes(password)
 new md5_password[34]
 md5(password, md5_password)
 if (equali(g_UserData[id][AuthSQL], md5_password))
 {
 format(g_UserData[id][AuthCodeNow], MAX_NAME_LEN, "%s", md5_password)
 /*g_bUserInfo[id][Login] = true
 remove_task(id)
 client_cmd(id, "slot1")
 client_color(id, id, "^x01[^x03%s^x01] ^x04登录成功", SERVER_NAME)
 access_user(id)
 exec_login_forward(id)*/


 remove_task(id)
 #if DEBUG
 server_print("check_auth_code type: %d",g_UserData[id][PlayerType]);
 #endif
 access_user(id)
 g_bUserInfo[id][Ignore_name_change] = false
 set_user_info(id, "name", g_UserData[id][ChsName])
 g_UserData[id][Login] = true;
 g_bUserInfo[id][CheckOver]  = true;
 g_bUserInfo[id][Data_not_found] = false;
 g_UserData[id][PlayerType] = get_user_type_ex(id)
 client_cmd(id, "slot1")
 client_color(id, id, "^x01[^x03%s^x01] ^x04登录成功", SERVER_NAME)
 exec_login_forward(id)
 }
 else if (++g_attempts[id] < MAX_LOGIN_ATTEMPT)
 {
 g_countdown[id] = COUNT_DOWN_FROM
 remove_task(id)
 set_task(1.0, "task_countdown", id)
 client_cmd(id, "messagemode enter_password")
 client_color(id, id, "^x01[^x03%s^x01 ^x03密码错误,请重新输入", SERVER_NAME)
 }
 else
 {
 remove_task(id)
 user_kick(id, "密码输入错误超过次数,若非本人注册请重新改名!")
 }
}


public show_login_menu(id)
{
 static title[128]
 static name[32]
 get_user_name(id, name, 31)
 formatex(title, 127, "\y用户名已注册,请按1后输入密码^n\w倒计时\r%d\w秒", g_countdown[id])
 if (g_countdown[id]-- <= 0)
 {
 user_kick(id, "密码输入超时,若非本人注册请重新改名")
 return
 }
 new menu = menu_create(title, "_show_login_menu")
 
 menu_additem(menu, "\w输入密码", NUM_1, 0)
 //menu_setprop(menu, MPROP_EXITNAME, "离开服务器")
 menu_setprop(menu, MPROP_EXIT, MEXIT_NEVER)
 bb_menu_display(id, menu, 0)


 set_task(1.0, "show_login_menu", id)
}


public _show_login_menu(id, menu, item)
{
 if (item == MENU_EXIT )
 {
 menu_destroy(menu)
 return
 }
 client_cmd(id, "messagemode enter_password")
 g_bUserInfo[id][Entering_pw] = true
 g_countdown[id] = COUNT_DOWN_FROM
 remove_task(id)
 set_task(1.0, "task_countdown", id)
 menu_destroy(menu)
}


public show_countdown_menu(id)
{
 static title[128]
 static name[32]
 get_user_name(id, name, 31)
 formatex(title, 127, "\y请输入密码^n\w倒计时\r%d\w秒", g_countdown[id])
 new menu = menu_create(title, "_show_countdown_menu")
 
 menu_additem(menu, "\w欢迎访问:www.cs-club.com")


 menu_setprop(menu, MPROP_EXIT, MEXIT_NEVER)
 bb_menu_display(id, menu, 0)
}


public _show_countdown_menu(id, menu, item)
{
 menu_destroy(menu)
}


public task_countdown(id)
{
 if (--g_countdown[id] > 0)
 {
 set_task(1.0, "task_countdown", id)
 show_countdown_menu(id)
 }
 else
 {
 user_kick(id, "密码输入超时,若是你注册的帐号则请想好密码再进入")
 }
}


public show_reg_menu(id)
{
 static title[128]
 static name[32]
 
 get_user_name(id, name, 31)
 //set_en_name(id, name)
 format(g_UserData[id][Name],MAX_NAME_LEN,"%s",name)
 
 replace(name, 31, UNREG_PREFIX, "")
 formatex(title, 127, "\y请注册 \r%s ^n\w注意:未注册玩家不计成绩", name)
 new menu = menu_create(title, "_show_reg_menu")
 if (g_bUserInfo[id][Steam])
 {
 menu_additem(menu, "\w注册名字(登录时需输入密码)", NUM_1, 0) 
 }
 else
 {
 menu_additem(menu, "\w注册^n\w(按1后看左上角输入并记住你喜欢的密码)", NUM_1, 0)
 }
 menu_setprop(menu, MPROP_EXITNAME, "退出")
 menu_setprop(menu, MPROP_EXIT, MEXIT_ALL)
 bb_menu_display(id, menu, 0)
}


public _show_reg_menu(id, menu, item)
{
 if (item == MENU_EXIT)
 {
 menu_destroy(menu)
 return
 }


 new data[1]
 static item_name[128]
 static access, callback
 //static auth[46]
 menu_item_getinfo(menu, item, access, data, 1, item_name, 127, callback)


 switch(data[0])
 {
 case '1':
 /*{
 get_user_authid(id, auth, 45)
 user_register(id, auth)
 }
 case '2':*/
 {
 get_user_name(id, g_UserData[id][VGName], 32)
 get_user_name(id, g_UserData[id][ChsName], 32)
 client_cmd(id, "messagemode reg_enter_password")
 g_bUserInfo[id][Entering_pw] = true
 }
 }
 
 menu_destroy(menu)
}




public user_register(id, const password[])
{
 static query[512]
 static name[32]
 /*if (g_UserData[id][Name][0])
 {
 copy(name, 31, g_UserData[id][Name])
 }
 else*/
 {
 static pos
 static tempname[32]
 get_user_name(id, tempname, 31)
 replace(tempname, 31, "[NO-sXe-I]", "")
 pos = containi(tempname, UNREG_PREFIX)
 if (pos != -1)
 {
 copy(name, 31, tempname[pos + strlen(UNREG_PREFIX)])
 set_user_info(id, "name", name)
 g_bUserInfo[id][Ignore_name_change] = true
 }
 else
 {
 copy(name, 31, tempname)
 }
 }
 formatex(query, charsmax(query), "INSERT INTO `%s` (`name`, `chsname`, `password`, `regdate`, `timestamp`) VALUES (_utf8^"%s^", _utf8^"%s^", ^"%s^", ^"%s^", %d) ON DUPLICATE KEY UPDATE `password` = ^"%s^";", SQL_TABLE_REG_INFO, name, name, password, g_str_date, get_systime(), password)


 new data[2]
 data[0] = id
 data[1] = get_user_userid(id)
 SQL_ThreadQuery(g_sql_tuple, "_user_register", query, data, 2)
}


public _user_register(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
{
 new id = data[0]
 new uid = data[1]
 if(uid != get_user_userid(id))
 id = get_user_real_index(uid)
 
 if (!is_user_connected(id))
 {
 return
 }
 if (failstate == TQUERY_CONNECT_FAILED)
 {
 #if DEBUG
 server_print("[%s] Cannot connect to MySQL server: %s", SERVER_NAME, error)
 #endif
 client_color(id, id, "^x01[^x03%s^x01] ^x04注册时出错,连接MySQL数据库失败", SERVER_NAME)
 return
 }
 else if (errcode)
 {
 server_print("[%s] user_register() - Query error: %s", SERVER_NAME, error)
 client_color(id, id, "^x01[^x03%s^x01] ^x04注册时出错,错误:%s", SERVER_NAME, error)
 return
 }
 else
 {
 g_bUserInfo[id][Login] = true
 g_bUserInfo[id][ChangeChsName] = true
 client_color(id, id, "^x01[^x03%s^x01] ^x04注册成功", SERVER_NAME)
 access_user(id)
 get_uid_by_name(id)
 }
}


public get_uid_by_name(id)
{
 static query[512]
 static name[32]
 get_user_name(id, name, 31)
 formatex(query, charsmax(query), "SELECT `index` FROM `%s` WHERE `name` = _utf8^"%s^" LIMIT 1;", SQL_TABLE_REG_INFO, name)
 
 #if DEBUG
 server_print(query)
 #endif
 
 new data[2]
 data[0] = id
 data[1] = get_user_userid(id)
 SQL_ThreadQuery(g_sql_tuple, "_get_uid_by_name", query, data, 2)
 g_bUserInfo[id][Querying] = true
}


public _get_uid_by_name(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
{
 new id = data[0]
 new uid = data[1]
 if(uid != get_user_userid(id))
 id = get_user_real_index(uid)
 
 if (!is_user_connected(id) || !g_bUserInfo[id][Querying])
 {
 g_bUserInfo[id][Querying] = false
 return
 }
 
 g_bUserInfo[id][Querying] = false
 if (failstate == TQUERY_CONNECT_FAILED)
 {
 server_print("[%s] Cannot connect to MySQL server: %s", SERVER_NAME, error)
 return
 }
 else if (errcode)
 {
 server_print("[%s] get_uid_by_name() - Qurey error: %s", SERVER_NAME, error)
 return
 }
 if (SQL_NumResults(query))
 {
 g_UserData[id][Index] = SQL_ReadResult(query, 0)
 
 g_bUserInfo[id][Ignore_name_change] = false
 g_UserData[id][Login] = true;
 g_bUserInfo[id][CheckOver]  = true;
 g_bUserInfo[id][Data_not_found] = false;
 g_UserData[id][PlayerType] = get_user_type_ex(id)
 exec_login_forward(id)


 #if DEBUG
 server_print("注册成功, uid:%d", g_UserData[id][Index])
 #endif
 }
}




public task_check_steam_status(tid)
{
 new id = tid - TASK_CHECK_QSTATUS
 if (!is_user_connected(id))
 return


 // 如果不是正版用户直接返回
 if (!g_bUserInfo[id][Steam])
 return
 
 // 如果正在查询数据库则等待
 if(g_bUserInfo[id][Querying])
 {
 set_task(1.1, "task_check_steam_status", tid)
 return
 }


 // 如果已经查找过用户
 if(g_bUserInfo[id][Data_not_found])
 {
 static name[32]
 get_user_name(id, name, 31)
 replace(name, 31, UNREG_PREFIX, "")
 
 #if DEBUG
 server_print("g_bUserInfo[id][Data_not_found], start reg: %s", name)
 #endif
 
 if (is_utf8_name(name))
 {
 user_kick(id, "请不要在正版steam中设置中文游戏名!")
 }
 else
 {
 show_reg_menu(id)
 return
 }
 }
 
 if (g_UserData[id][AuthSQL][0])
 {
 g_countdown[id] = COUNT_DOWN_FROM
 show_login_menu(id)
 return
 } 
}
#endif


#if WITH_UNREG_PREFIX
stock add_unreg_prefix(id, name[])
{
 if (containi(name, UNREG_PREFIX) == -1)
 {
 format(name, 31, "%s%s", UNREG_PREFIX, name)
 set_user_info(id, "name", name)
 }
 
 format(g_UserData[id][Name],MAX_NAME_LEN,"%s",name)
 format(g_UserData[id][ChsName],MAX_NAME_LEN,"%s",name)
 g_bUserInfo[id][ChangeChsName] = false
 g_bUserInfo[id][Err_prefix] = true
}
#endif


stock get_strdate(out[], year, month, day)
{
 out[0] = DIGIT_TO_CHAR[year / 1000]
 out[1] = DIGIT_TO_CHAR[(year % 1000) / 100]
 out[2] = DIGIT_TO_CHAR[(year % 100) / 10]
 out[3] = DIGIT_TO_CHAR[year % 10]
 out[4] = DIGIT_TO_CHAR[month / 10]
 out[5] = DIGIT_TO_CHAR[month % 10]
 out[6] = DIGIT_TO_CHAR[day / 10]
 out[7] = DIGIT_TO_CHAR[day % 10]
 out[8] = 0
}


stock get_previous_day(out[], year, month, day)
{
 if (day-- == 1)
 {
 if (month-- == 1)
 {
 year--
 month = 12
 day = 31
 }
 else
 {
 day = DAYS_IN_MONTH[month]
 }
 }
 get_strdate(out, year, month, day)
}


stock get_next_day(out[], year, month, day)
{
 if (day++ >= DAYS_IN_MONTH[month])
 {
 if (month++ == 12)
 {
 year++
 month = 1
 day = 1
 }
 else
 {
 day = 1
 }
 }
 get_strdate(out, year, month, day)
}


// 获取当前时间之少天之后的时间
stock get_vip_day_string(out[], size, dayAdd)
{
 new year, month, day
 date(year, month, day)
 if ((day + dayAdd) >= DAYS_IN_MONTH[month])
 {
 if (month++ == 12)
 {
 year++
 month = 1
 day = 1
 }
 else
 {
 day = day + dayAdd
 }
 }
 else
 {
 day = day + dayAdd
 }
 
 format(out, size, "%04d-%02d-%02d", year, month, day)
}


stock bool:is_outdated(const str_exp_date[], len)
{
 if (!str_exp_date[0])
 {
 return false
 }
 new str_ymd[3][5]
 static i, digit_counter, chr, chr_counter
 digit_counter = 0
 chr_counter = 0
 for (i = 0; i < len; i++)
 {
 chr = str_exp_date[i]
 if (chr == '-')
 {
 chr_counter = 0
 if (++digit_counter > 2)
 {
 server_print("日期格式错误: 符号'-'数量过多. 表格:`%s` 字段:`exp_date` 值: '%s'" , SQL_TABLE_REG_INFO, str_exp_date)
 return false
 }
 }
 else if ('0' <= chr <= '9')
 {
 str_ymd[digit_counter][chr_counter++] = chr
 }
 else if (chr == 0)
 {
 break
 }
 else
 {
 server_print("日期格式错误: 不能出现(数字0到9以及-)以外的任何字符. 表格:`%s` 字段:`exp_date` 值: '%s'" , SQL_TABLE_REG_INFO, str_exp_date)
 return false
 }


 }
 if (digit_counter < 2)
 {
 server_print("日期格式错误: 符号'-'数量过少. 表格:`%s` 字段:`exp_date` 值: '%s'" , SQL_TABLE_REG_INFO, str_exp_date)
 return false
 }
 if (str_to_num(str_ymd[0]) * 372 + str_to_num(str_ymd[1]) * 31 + str_to_num(str_ymd[2]) < g_year * 372 + g_month * 31 + g_day)
 {
 return true
 }
 return false
}


///////////////////////////////////////////////////////////////////////////////////////////
//
// native api for other plugins
//
public plugin_natives()
{
 register_library("mt_login")
 register_native("get_user_uid", "_get_user_uid")
 register_native("get_user_type", "_get_user_type")
 register_native("get_user_engname", "_get_user_engname")
 register_native("get_user_chsname", "_get_user_chsname")
 register_native("get_user_qq","_get_user_qq")
 register_native("get_user_signature", "_get_user_signature")
 //register_native("get_vip_string", "_get_vip_string")
 register_native("get_vip_flag", "_get_vip_flag")
 register_native("get_exp_date", "_get_exp_date")
 register_native("get_reg_date", "_get_reg_date")


 register_native("log_admin_mysql","_log_admin_mysql")
 
 register_native("get_sql_host", "_get_sql_host")
 register_native("get_sql_user", "_get_sql_user")
 register_native("get_sql_pass", "_get_sql_pass")
 register_native("get_sql_db", "_get_sql_db")
}


public _get_user_uid(iPlugin,iParams)
{
 if(iParams != 1)
 {
 server_print ("get_user_uid() - incorrect param num") 
 return 0
 }
 
 new id = get_param(1)
 if(is_player(id))
 {
 if(get_user_type(id) == MT_UNREG)
 return 0
 
 return g_UserData[id][Index]
 }


 return 0
}


public _get_user_type(iPlugin,iParams)
{
 if(iParams != 1)
 {
 server_print ("get_user_type() - incorrect param num") 
 return MT_UNKNOW
 }
 
 //return get_user_type(get_param(1))
 new id = get_param(1)
 if(is_player(id))
 return g_UserData[id][PlayerType];


 return MT_UNREG
}


public _get_user_engname(iPlugin,iParams)
{
 if (iParams != 3)
 {
 server_print ("get_user_engname() - incorrect param num") 
 return 0
 }
 
 new len = get_param(3)
 new id  = get_param(1)
 new size = 0
 new string[33]
 
 if(is_player(id))
 {
 size = strlen(g_UserData[id][VGName]) + 1
 if(size > len)
 size = len


 format(string,MAX_NAME_LEN,"%s",g_UserData[id][VGName])
 if(strlen(string) == 0)
 {
 get_user_name(id, string, 31)
 size = strlen(string);
 }
 
 #if DEBUG
 server_print("name: %d - %s - %s - %s", size, g_UserData[id][VGName], string, g_UserData[id][ChsName])
 #endif
 set_string(2, string, size)
 return 1
 }
 
 return 0
}


public _get_user_chsname(iPlugin,iParams)
{
 if (iParams != 3)
 {
 server_print ("_get_user_chsname() - incorrect param num") 
 return 0
 }
 
 new len = get_param(3)
 new id  = get_param(1)
 new size = 0
 
 if(is_player(id))
 {
 size = strlen(g_UserData[id][ChsName])
 if(size > len)
 size = len
 
 set_string(2, g_UserData[id][ChsName], size)
 return 1
 }
 
 return 0
}


public _get_user_qq(iPlugin,iParams)
{
 if (iParams != 3)
 {
 server_print ("_get_user_qq() - incorrect param num") 
 return 0
 }
 
 new len = get_param(3)
 new id  = get_param(1)
 new size = 0
 
 if(is_player(id))
 {
 size = strlen(g_UserData[id][QQ])
 if(size > len)
 size = len
 
 set_string(2, g_UserData[id][QQ], size)
 return 1
 }
 
 return 0
}


public _get_user_signature(iPlugin,iParams)
{
 if (iParams != 3)
 {
 server_print ("get_user_signature() - incorrect param num") 
 return 0
 }
 new id  = get_param(1)
 new len = get_param(3)
 new size = 0
 
 if(is_player(id))
 {
 size = strlen(g_UserData[id][Signature])
 if(size > len)
 size = len
 
 set_string(2, g_UserData[id][Signature], size)
 return 1
 }


 return 0
}


public _get_vip_string(iPlugin,iParams)
{
 if (iParams != 3)
 {
 //server_print ("_get_vip_string() - incorrect param num") 
 return 0
 }


 new id  = get_param(1)
 new len = get_param(3)
 new type = get_user_type(id)
 new string[127]
 
 if(!is_player(id))
 return 0
 
 if(type == MT_NONSTEAM)
 formatex(string, charsmax(string), "%s", member[type])
 else
 formatex(string, charsmax(string), "未注册")


 set_string(2, string, len > 127 ? 127 : len)
 return 1
}


// 获取用户权限字母
public _get_vip_flag(iPlugin,iParams)
{
 if (iParams != 3)
 {
 //server_print ("_get_vip_flag() - incorrect param num") 
 return 0
 }


 new id  = get_param(1)
 new len = get_param(3)
 new string[33]
 
 if(!is_player(id))
 return 0
 
 if(strlen(g_UserData[id][AccessStr]))
 formatex(string, charsmax(string), "%s", g_UserData[id][AccessStr])
 else
 formatex(string, charsmax(string), "z")


 set_string(2, string, len > 32 ? 32 : len)
 return 1
}


// 获取VIP到期时间
public _get_exp_date(iPlugin,iParams)
{
 if (iParams != 3)
 {
 //server_print ("_get_exp_date() - incorrect param num") 
 return 0
 }


 new id  = get_param(1)
 new len = get_param(3)
 new string[33]
 
 if(!is_player(id))
 return 0
 
 if(strlen(g_UserData[id][VipDate]))
 formatex(string, charsmax(string), "%s", g_UserData[id][VipDate])
 else
 formatex(string, charsmax(string), "")


 set_string(2, string, len > 32 ? 32 : len)
 return 1
}


// 获取注册时间
public _get_reg_date(iPlugin,iParams)
{
 if (iParams != 3)
 {
 //server_print ("_get_reg_date() - incorrect param num") 
 return 0
 }


 new id  = get_param(1)
 new len = get_param(3)
 new string[33]
 
 if(!is_player(id))
 return 0
 
 if(strlen(g_UserData[id][RegDate]))
 formatex(string, charsmax(string), "%s", g_UserData[id][RegDate])
 else
 formatex(string, charsmax(string), "2022-05-01")


 set_string(2, string, len > 32 ? 32 : len)
 return 1
}


public _log_admin_mysql(iPlugin,iParams)
{
 if (iParams != 1)
 {
 server_print ("_log_admin_mysql() - incorrect param num") 
 return 0
 }
 
 new string[512]
 get_string(1, string, 512)
 my_log_admin_mysql(string)
 return 1
}


public my_log_admin_mysql(const string[])
{   
    // stop the plugin with an error message
    new query[512]
    new szTime[24]
    new srvName[256]


 if(g_sql_tuple == Empty_Handle)
        return 0
 
 get_pcvar_string(pc_log_srv, srvName, 255) 
    format_time(szTime,24,"%Y-%m-%d %H:%M:%S")
    formatex(query,charsmax(query),"INSERT INTO `%s` (`log_time`,`log_server`,`log_msg`) VALUES (_utf8'%s',_utf8'%s',_utf8^"%s^")",SQL_TABLE_LOG_ADMIN,szTime,srvName,string) 
    if(!g_mapchange_started)
 {
 SQL_ThreadQuery(g_sql_tuple, "IgnoreHandle"/*"_log_admin_mysql_sql"*/, query)
 return 1;
 }
 
 return 0;
}


// 获取数据库地址
public _get_sql_host(iPlugin,iParams)
{
 if (iParams != 2)
 {
 server_print ("_get_sql_host() - incorrect param num") 
 return 0
 }


 new len = get_param(2)
 new host[MAX_SG_LEN]


 get_pcvar_string(pc_sql_host, host, MAX_SG_LEN - 1)
 set_string(1, host, len > MAX_SG_LEN ? MAX_SG_LEN : len)
 return 1
}


// 获取数据库用户名
public _get_sql_user(iPlugin,iParams)
{
 if (iParams != 2)
 {
 server_print ("_get_sql_user() - incorrect param num") 
 return 0
 }
 
 new len = get_param(2)
 new user[MAX_SG_LEN]
 
 get_pcvar_string(pc_sql_user, user, MAX_SG_LEN - 1)
 set_string(1, user, len > MAX_SG_LEN ? MAX_SG_LEN : len)
 return 1
}


// 获取数据库用户名
public _get_sql_pass(iPlugin,iParams)
{
 if (iParams != 2)
 {
 server_print ("_get_sql_pass() - incorrect param num") 
 return 0
 }
 
 new len = get_param(2)
 new pass[MAX_SG_LEN]


 get_pcvar_string(pc_sql_pass, pass, MAX_SG_LEN - 1)
 set_string(1, pass, len > MAX_SG_LEN ? MAX_SG_LEN : len)
 return 1
}


// 获取数据库名
public _get_sql_db(iPlugin,iParams)
{
 if (iParams != 2)
 {
 server_print ("_get_sql_pass() - incorrect param num") 
 return 0
 }
 
 new len = get_param(2)
 new db[MAX_SG_LEN]


 get_pcvar_string(pc_sql_db, db, MAX_SG_LEN - 1)
 set_string(1, db, len > MAX_SG_LEN ? MAX_SG_LEN : len)
 return 1
}






public IgnoreHandle(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
{
 if (failstate == TQUERY_CONNECT_FAILED)
 {
 #if DEBUG
 server_print("[%s] Cannot connect to MySQL server: %s", SERVER_NAME, error)
 #endif
 }
 else if (errcode)
 {
 #if DEBUG
 server_print("[%s] user_register() - Query error: %s", SERVER_NAME, error)
 #endif
 }
 else{}
}
///////////////////////////////////////////////////////////////////////////////////////////


public make_sql_tuple()
{
 new host[64], user[32], pass[32], db[32]
 get_pcvar_string(pc_sql_host, host, 63)
 get_pcvar_string(pc_sql_user, user, 31)
 get_pcvar_string(pc_sql_pass, pass, 31)
 get_pcvar_string(pc_sql_db, db, 31)
 g_sql_tuple = SQL_MakeDbTuple(host, user, pass, db)
 #if DEBUG
 server_print("[Login] host %s user %s pass %s db %s, handle %d", host, user, pass, db, g_sql_tuple)
 #endif


#if MYSQL_CHECK
 set_task(3.0, "check_table", 9491)
#endif
}


public save_xp(id, uid, xp)
{
 static query[256]
 if (is_player(id) && uid > 0)
 {
 formatex(query, charsmax(query), "UPDATE `%s` SET `xp` = %d WHERE `index` = %d LIMIT 1;", SQL_TABLE_REG_INFO, xp, uid)
 if(!g_mapchange_started)
 SQL_ThreadQuery(g_sql_tuple, "_save_xp", query)
 }
}


public _save_xp(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
{
 if (failstate == TQUERY_CONNECT_FAILED)
 {
 #if DEBUG
 server_print("[%s] Cannot connect to MySQL server: %s", SERVER_NAME, error)
 #endif
 }
 else if (errcode)
 {
 #if DEBUG
 server_print("[%s] save_xp() - Qurey error: %s  errcode: %d", SERVER_NAME, error, errcode)
 #endif
 }
}


public get_user_type_ex(id)
{
 if (is_user_connected(id) && !is_user_bot(id))
 {
 if(g_bUserInfo[id][Err_prefix] || !g_bUserInfo[id][CheckOver] || is_user_bot(id)/* || vg_getstatus(id) == 0*/)
 {
 #if DEBUG
 client_print(id,print_chat,"get_user_type(%d) g_bUserInfo[id][Err_prefix]:%d  g_bUserInfo[id][CheckOver]:%d  bot:%d vgstatus:%d.", 
 id,g_bUserInfo[id][Err_prefix],g_bUserInfo[id][CheckOver],is_user_bot(id), vg_getstatus(id))
 server_print("get_user_type(%d) g_bUserInfo[id][Err_prefix]:%d  g_bUserInfo[id][CheckOver]:%d  bot:%d vgstatus:%d.", 
 id,g_bUserInfo[id][Err_prefix],g_bUserInfo[id][CheckOver],is_user_bot(id), vg_getstatus(id))
 #endif
 return MT_UNREG
 }


 return MT_NONSTEAM
 }
 
 return MT_UNREG
}


public get_user_type(id)
{
 if (is_user_connected(id) && !is_user_bot(id))
 {
 if(g_bUserInfo[id][Err_prefix] || !g_bUserInfo[id][CheckOver] || is_user_bot(id)/* || vg_getstatus(id) == 0*/)
 {
 return MT_UNREG
 }


 if (!g_UserData[id][Login])
 {
 return MT_UNREG
 }
 return MT_NONSTEAM
 }
 
 return MT_UNREG
}


public plugin_cfg()
{
 set_task(0.01, "make_sql_tuple")
 format(g_log_Error, 255, "MTError%04d%02d%02d.log", g_year, g_month, g_day)
 format(g_log_Login, 255, "MTLogin%04d%02d%02d.log", g_year, g_month, g_day)
 format(g_log_Shop,  255, "MTShop%04d%02d%02d.log",  g_year, g_month, g_day)
}


public fwd_jointeam()
{
 new id = read_data(1)
 
 if(is_user_bot(id))
 return


 if (!g_bUserInfo[id][Joined_team])
 {
 g_bUserInfo[id][Joined_team] = true
 //client_cmd(id, "hud_centerid 0")
 
 // 检查未注册
 if (!g_bUserInfo[id][CheckOver] || g_UserData[id][PlayerType] == MT_UNKNOW)
 {
 if(!task_exists(id + TASK_ID_LOGIN) && !g_bUserInfo[id][Querying] && !g_bUserInfo[id][FindUser])
 {
 set_task(5.0, "task_login", id + TASK_ID_LOGIN)
 return
 }
 }
 }
 
 if(get_pcvar_num(pc_vg_kick) != 0)
 {
 if(!task_exists(id + TASK_ID_KICK))
 set_task(5.0, "task_check_kick", id + TASK_ID_KICK)
 }
}


public fwd_ClientUserInfoChanged(id, buffer)
{
 static oldname[32]
 static newname[32]
 
 if(!is_player(id) || is_user_bot(id))
 return FMRES_IGNORED
 
 if(is_user_hltv(id) || !g_bUserInfo[id][Put_in_server])
 return FMRES_IGNORED
 
 get_user_name(id, oldname, 31)
 get_user_info(id, "name", newname, 31)
 
 // 如果是相同的名字就不提示
 if(equal(oldname, newname))
 return FMRES_SUPERCEDE
 
 // 如果是登录器首次会员改名,则放行
 #if DEBUG
 server_print("oldName:%s newName:%s",oldname,newname)
 #endif
 
 if(containi(oldname, UNREG_PREFIX) != -1)
 {
 set_user_info(id, "name", oldname);
 return FMRES_SUPERCEDE
 }


 if((g_bUserInfo[id][Steam]/* || vg_getstatus(id) != 0*/) && !g_bUserInfo[id][ChangeChsName])
 {
 g_bUserInfo[id][ChangeChsName] = true
 g_bUserInfo[id][Ignore_name_change] = true
 if (equal(g_UserData[id][ChsName], newname) && newname[0])
 {
 set_user_info(id, "name", newname);
 g_bUserInfo[id][Ignore_name_change] = true
 }
 else
 {
 if(g_UserData[id][PlayerType] != MT_UNKNOW)
 {
 if (containi(newname, UNREG_PREFIX) != -1)
 {
 set_user_info(id, "name", newname);
 //format(g_UserData[id][Name], MAX_NAME_LEN, "%s", newname)
 format(g_UserData[id][ChsName], MAX_NAME_LEN, "%s", newname)
 server_print("fwd_ClientUserInfoChanged1 name: %s", g_UserData[id][Name])
 }
 }
 }


 return FMRES_SUPERCEDE
 }
 
 // 未注册Error标记
 if(g_bUserInfo[id][Err_prefix] && !g_bUserInfo[id][ChangeChsName])
 {
 g_bUserInfo[id][ChangeChsName] = true
 g_bUserInfo[id][Ignore_name_change] = true
 if (equal(g_UserData[id][ChsName], newname) && newname[0])
 {
 set_user_info(id, "name", newname);
 g_bUserInfo[id][Ignore_name_change] = true
 }
 else
 {
 if (containi(newname, UNREG_PREFIX) != -1)
 {
 set_user_info(id, "name", newname);
 g_bUserInfo[id][Ignore_name_change] = true
 format(g_UserData[id][Name], MAX_NAME_LEN, "%s", newname)
 server_print("fwd_ClientUserInfoChanged2 name: %s", g_UserData[id][Name])
 return FMRES_SUPERCEDE
 }
 else
 {
 format(newname, 31, "%s", g_UserData[id][Name])
 set_user_info(id, "name", newname);
 }
 }
 return FMRES_SUPERCEDE
 }
 
 if (g_bUserInfo[id][Ignore_name_change])
 {
 if (!equal(oldname, newname) && oldname[0])
 {
 set_user_info(id, "name", oldname);
 }
 return FMRES_SUPERCEDE
 }


 return FMRES_IGNORED
}


public fwd_Spawn(id)
{
 if (!is_user_alive(id) || is_user_bot(id))
 return


 // 是否有错误提示
 if (g_show_errmsg[id] > 0)
 {
 set_task(6.0, "task_show_errmsg", id + TASK_ID_ERRMSG)
 }
 
 // 已经登录过的不用管
 if (g_bUserInfo[id][Err_prefix] || g_bUserInfo[id][Login] || g_bUserInfo[id][Data_not_found])
 return
 
 // 检查未注册
 if (!g_bUserInfo[id][FindUser] || g_UserData[id][PlayerType] == MT_UNKNOW)
 {
 if(!task_exists(id + TASK_ID_LOGIN))
 {
 set_task(5.0, "task_login", id + TASK_ID_LOGIN)
 }
 }
}


public task_show_errmsg(tid)
{
 new id = tid - TASK_ID_ERRMSG
 show_errmsg(id)
}


stock show_errmsg(id)
{
 set_hudmessage(255, 25, 26, 0.88, 0.61, 1, 10.0, 10.0, _, _, 3)
 show_hudmessage(id, MSG_ERRORS[g_errcode[id]])
}


stock user_check_or_kick(id)
{
 if(!is_player(id))
 return
 
 if(g_UserData[id][PlayerType] >= MT_NONSTEAM || g_UserData[id][PlayerType] == MT_UNKNOW || !g_bUserInfo[id][AccessUser])
 return
 
 new opt = get_pcvar_num(pc_vg_kick)
 if(opt == 1)
 {
 user_kick(id, "本服强制使用登录器,请加群58374402或官网www.CS-Pub.com下载!")
 return
 }
 else if(opt == 2)
 {
 if(cs_get_user_team(id) == CS_TEAM_UNASSIGNED || cs_get_user_team(id) == CS_TEAM_SPECTATOR)
 return
 
 user_silentkill(id)
 cs_set_user_team(id,CS_TEAM_SPECTATOR)
 client_color(id, id, "^x01[^x03%s^x01] 本服务器^x04强制使用登录器^x01,^x03未开VGuard反作弊将只允许M6观察模式化^x01",SERVER_NAME)
 }
}


stock user_error(id, err_code)
{
 if(is_user_bot(id))
 return
 
 #if DEBUG
 server_print("user_error: %d %d",id,err_code)
 #endif
 
 #if WITH_UNREG_PREFIX
 static name[32]
 get_user_name(id, name, 31)
 add_unreg_prefix(id, name)
 #endif


 g_bUserInfo[id][CheckOver]  = true
 g_UserData[id][PlayerType]  = MT_UNREG
 g_bUserInfo[id][AccessUser] = true
 g_show_errmsg[id] = 0
 g_errcode[id] = err_code
 if(get_pcvar_num(pc_vg_kick) != 0)
 {
 if(!task_exists(id + TASK_ID_KICK))
 set_task(0.5, "task_check_kick", id + TASK_ID_KICK)
 }
 show_errmsg(id)
}


public task_check_kick(tid)
{
 new id = tid - TASK_ID_KICK
 if(!is_player(id))
 return
 
 user_check_or_kick(id)
}


stock exec_login_forward(id)
{
 static query[512]
 static name[32]
 static ip[33]
 static ret
 
 get_user_ip(id, ip, 31, 1)
 if (g_UserData[id][Name][0])
 {
 copy(name, 31, g_UserData[id][Name])
 }
 else
 {
 get_user_name(id, name, 31)
 if (remove_prefixes(name))
 {
 set_user_info(id, "name", name)
 g_bUserInfo[id][Ignore_name_change] = true
 }
 }
 
 if (g_sql_tuple != Empty_Handle)
 {
 formatex(query, charsmax(query), "UPDATE `%s` SET `lastlogin` = ^"%s^",`ip` = ^"%s^", `timestamp` = %d WHERE `index` = ^"%u^" LIMIT 1;", SQL_TABLE_REG_INFO, g_str_date, ip, get_systime(), g_UserData[id][Index])
 if(!g_mapchange_started)
 SQL_ThreadQuery(g_sql_tuple, "_user_set_login_date", query)
 }


 if (g_UserData[id][Name][0])
 {
 get_user_name(id, name, 31)
 }
 
 if (g_UserData[id][ChsName][0])
 {
 if (!equali(g_UserData[id][ChsName], name))
 {
 set_user_info(id, "name", g_UserData[id][ChsName])
 g_bUserInfo[id][Ignore_name_change] = true
 }
 }
 else if (g_UserData[id][Name][0] && !equali(g_UserData[id][Name], name))
 {
 set_user_info(id, "name", g_UserData[id][Name])
 g_bUserInfo[id][Ignore_name_change] = true
 }


 if (g_forward == -1)
 {
 server_print("Invalid forward handler.")
 return -1
 }
 
 #if DEBUG
 server_print("exec_login_forward name: %s", g_UserData[id][Name])
 #endif
 
 #if DEBUG
 server_print("id:%d  index:%d  exp:%d  PlayerType:%d", id, g_UserData[id][Index], g_UserData[id][Exp], g_UserData[id][PlayerType])
 #endif


 if (!ExecuteForward(g_forward, ret, id, g_UserData[id][Index], g_UserData[id][Exp], g_UserData[id][PlayerType]))
 {
 server_print("Could not execute forward")
 }
 return ret
}


public _user_set_login_date(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
{
}


public mt_init_config()
{
 register_cvar("amx_vote_ratio", "0.02")
 register_cvar("amx_vote_time", "10")
 register_cvar("amx_vote_answers", "1")
 register_cvar("amx_vote_delay", "30")
 register_cvar("amx_last_voting", "0")
 register_cvar("amx_show_activity", "2")
 register_cvar("amx_votekick_ratio", "0.40")
 register_cvar("amx_voteban_ratio", "0.40")
 register_cvar("amx_votemap_ratio", "0.40")
 set_cvar_float("amx_last_voting", 0.0)
 remove_user_flags(0, read_flags("z")) // Remove 'user' flag from server rights
 
 new configsDir[64]
 get_configsdir(configsDir, 63)
 server_cmd("exec %s/amxx.cfg", configsDir) // Execute main configuration file
 
 g_maxplayers = get_maxplayers()
 if (g_maxplayers > 32)
 {
 g_maxplayers = 32
 }
 
 check_date()
}


// id,userid,ret,szUser[],szPass[],szMac[]
public mi_guard_login(id, userid, ver, szUser[], szPass[], szMac[])
{
 static msg[192]
 new nID = id;
 new ip[24]
 new name[33]


 if(!is_player(id))
 return
 
 // 此处一定要检查一下UID跟ID是不是对应,否则重新查找id
 if(userid != get_user_userid(nID))
 nID = get_user_real_index(userid)
 
 // 如果SQL还没查找玩就不处理
 //if(!g_bUserInfo[id][FindUser])
 // return
 
 // 如果登录过就不再检查后续
 g_UserData[id][ClientVerion] = ver
 if(g_UserData[id][Index] || g_bUserInfo[id][Err_prefix] || g_bUserInfo[nID][Login] || g_bUserInfo[nID][CheckOver] || g_bUserInfo[nID][Querying])
 {
 g_bLoginPacketCnt[id] = 0;
 return
 }
 
 // 标记已经登录过
 /*g_bLoginPacketCnt[id]++;
 if(g_bLoginPacketCnt[id] >= 5)
 {
 mi_guard_netreset();
 g_bLoginPacketCnt[id] = 0;
 return;
 }*/
 get_user_ip(nID,ip,23,1)
 get_user_name(nID,name,32)
 g_bUserInfo[nID][VGuard] = true
 
 /*for(i=0; i<MAX_NAME_LEN; i++)
 g_UserData[nID][Name][i] = 0;
 for(i=0; i<MAX_NAME_LEN; i++)
 g_UserData[nID][AuthCodeNow][i] = 0;*/


 if(g_UserData[nID][VGName][0] == 0)
 format(g_UserData[nID][VGName],MAX_NAME_LEN,"%s",szUser)
 
 if(g_UserData[nID][AuthCodeNow][0] == 0)
 format(g_UserData[nID][AuthCodeNow],MAX_NAME_LEN,"%s",szPass)


 #if DEBUG
 formatex(msg, charsmax(msg), "id:%d userid:%d user:%d pass:%s sqlpass:%s", nID, userid, name, g_UserData[nID][AuthCodeNow], g_UserData[nID][AuthSQL])
 server_print(msg)
 
 formatex(msg, charsmax(msg), "id:%d userid:%d index:%d name:%s ip:%s mac:%s", nID, userid, g_UserData[nID][Index], name, ip, szMac)
 server_print(msg)
 #endif
 
 if((get_gametime() - g_bLoginLog[nID]) > 5.00)
 {
 g_bLoginLog[nID] = get_gametime()
 login_log(msg)
 }
 
 if(!task_exists(nID + TASK_ID_LOGIN))
 set_task(0.1, "task_login", nID + TASK_ID_LOGIN)
 
 #if DEBUG
 //server_print("szUser:%s,szPass:%s strlen(Name):%d",szUser,szPass,strlen(g_UserData[nID][Name]))
 //server_print("id:%d-%d,ret:%d,User:%s,Pass:%s,Mac:%s",id,userid,ret,szUser,g_UserData[nID][AuthCodeNow],szMac)
 #endif
}


public task_login(tid)
{
 new id = tid - TASK_ID_LOGIN
 if (is_player(id) && is_user_connected(id) && g_bUserInfo[id][Put_in_server] && !g_bUserInfo[id][FindUser])
 {
 g_bUserInfo[id][FindUser]= true;
 find_user(id)
 }
 else
 {
 #if DEBUG
 server_print("task_login: g_bUserInfo[id][Put_in_server]:%d",g_bUserInfo[id][Put_in_server])
 #endif
 }
}


public find_user(id)
{
 if(is_user_bot(id))
 return
 
 if(g_mapchange_started)
 return


 if (g_sql_tuple == Empty_Handle)
 {
 #if DEBUG
 server_print("find_user g_sql_tuple == Empty_Handle")
 #endif
 return
 }


 if(g_bUserInfo[id][Querying])
 {
 #if DEBUG
 server_print("find_user g_bUserInfo[id][Querying] = true")
 #endif
 return
 }
 
 if(!strlen(g_UserData[id][AuthCodeNow]) == 0)
 {
 if(g_bUserInfo[id][Steam])
 {
 #if DEBUG
 server_print("user erro authcodeNow %s.", g_UserData[id][AuthCodeNow])
 #endif
 user_error(id,MT_ERR_NOVG)
 return;
 } 
 }


 static query[512]
 static name[32]
 //get_user_name(id, name, 31)
 formatex(name, 31, "%s", g_UserData[id][Name])
 remove_prefixes(name)


 #if DEBUG
 server_print("find_user name: %s", g_UserData[id][Name])
 #endif
 
 if(!is_steam(id))
 {
 formatex(query, charsmax(query), "SELECT `index`, `password`, BINARY `signature`, `access`, `exp_date`, `name`, BINARY `chsname`, `xp`, `QQ` FROM `%s` \
 WHERE (`name` = _utf8^"%s^" OR `chsname` = _utf8^"%s^") AND `password` = ^"%s^" LIMIT 1;", SQL_TABLE_REG_INFO, name, name, g_UserData[id][AuthCodeNow])
 }
 else
 {
 formatex(query, charsmax(query), "SELECT `index`, `password`, BINARY `signature`, `access`, `exp_date`, `name`, BINARY `chsname`, `xp`, `QQ` FROM `%s` \
 WHERE (`name` = _utf8^"%s^" OR `chsname` = _utf8^"%s^") LIMIT 1;", SQL_TABLE_REG_INFO, name, name)
 }
 
 new data[2]
 data[0] = id
 data[1] = get_user_userid(id)
 
#if DEBUG
 server_print("%s", query)
#endif
 SQL_ThreadQuery(g_sql_tuple, "_find_user", query, data, 2)


 g_bUserInfo[id][Querying] = true
}


public clearn_user(id)
{
}


public _find_user(failstate, Handle:query, error[], errcode, data[], datasize, Float:queuetime)
{
 new id = data[0]
 new uid = data[1]
 if(uid != get_user_userid(id))
 id = get_user_real_index(uid)
 
 #if DEBUG
 server_print("sql _find_user start");
 #endif
 if (!is_user_connected(id) || !g_bUserInfo[id][Querying] || !g_bUserInfo[id][Put_in_server] || g_bUserInfo[id][Err_prefix])
 {
 g_bUserInfo[id][Querying] = false
 client_color(id, id, "^x01[^x03%s^x01] ^x04g_bUserInfo[id][Querying] = false", SERVER_NAME)
 #if DEBUG
 server_print("sql _find_user error 1.");
 #endif
 return
 }
 
 g_bUserInfo[id][Querying] = false
 if (failstate == TQUERY_CONNECT_FAILED)
 {
 #if DEBUG
 server_print("[%s] Cannot connect to MySQL server: %s", SERVER_NAME, error)
 client_color(id, id, "^x01[^x03%s^x01] ^x04不能连接MySQL服务器", SERVER_NAME)
 #endif
 return
 }
 else if (errcode)
 {
 #if DEBUG
 server_print("[%s] find_user()- Query error: %s", SERVER_NAME, error)
 client_color(id, id, "^x01[^x03%s^x01] ^x04获取数据时出错", SERVER_NAME)
 #endif
 return
 }
 
 //new counter
 #if DEBUG
 server_print("sql _find_user SQL_NumResults:");
 #endif
 if (SQL_NumResults(query))
 {
 while (SQL_MoreResults(query))
 {
 g_UserData[id][Index] = SQL_ReadResult(query, 0)
 SQL_ReadResult(query, 1, g_UserData[id][AuthSQL], MAX_NAME_LEN - 1)
 SQL_ReadResult(query, 2, g_UserData[id][Signature], MAX_SG_LEN - 1)
 SQL_ReadResult(query, 3, g_UserData[id][AccessStr], MAX_NAME_LEN - 1)
 SQL_ReadResult(query, 4, g_UserData[id][VipDate], 31)
 SQL_ReadResult(query, 5, g_UserData[id][Name], 31)
 SQL_ReadResult(query, 6, g_UserData[id][ChsName], 31)
 g_UserData[id][Exp] = SQL_ReadResult(query, 7)
 SQL_ReadResult(query, 8, g_UserData[id][QQ], 31)


 #if DEBUG
 server_print("xfind_user name: %s", g_UserData[id][Name])
 #endif
 
 #if DEBUG
 client_print(id, print_chat, "你的权限: %s", g_UserData[id][AccessStr]);
 server_print("your access str: %s", g_UserData[id][AccessStr]);
 #endif
 
 if(strlen(g_UserData[id][AccessStr]) == 0)
 {
 g_UserData[id][AccessInt]  = 0
 clearn_user(id)
 }
 else
 {
 if (strlen(g_UserData[id][VipDate])!= 0)
 {
 if(is_outdated(g_UserData[id][VipDate], 10))
 {
 g_UserData[id][AccessInt] = 0
 clearn_user(id)
 }
 else
 {
 g_UserData[id][AccessInt] = read_flags(g_UserData[id][AccessStr])
 }
 }
 else
 {
 g_UserData[id][AccessInt] = read_flags(g_UserData[id][AccessStr])
 }
 }
 
 //counter++
 #if DEBUG
 server_print("sql _find_user check_auth_code: %s %s", g_UserData[id][Name], g_UserData[id][AuthSQL]);
 #endif
 
 check_auth_code(id)
 
 #if DEBUG
 client_print(id,print_chat,"qq:%s access:%s type:%d",g_UserData[id][QQ],g_UserData[id][AccessStr],g_UserData[id][PlayerType])
 #endif
 SQL_NextRow(query)
 }
 }
 else
 {
 // 如果是正版用户,则提示注册
 if(g_bUserInfo[id][Steam])
 {
 g_bUserInfo[id][Data_not_found] = true
 g_bUserInfo[id][Querying]    = false;
 g_bUserInfo[id][CheckOver]   = false;
 g_bUserInfo[id][Ignore_name_change] = false;
 set_task(1.0, "task_check_steam_status", id + TASK_CHECK_QSTATUS)
 return;
 }
 
#if WITH_UNREG_PREFIX
 //static name[32]
 //get_user_name(id, name, 31)
 //add_unreg_prefix(id, name)
#endif
 user_error(id,MT_ERR_PASS)
 #if DEBUG
 server_print("sql _find_user not found:");
 #endif
 g_UserData[id][PlayerType] = MT_UNREG
 g_bUserInfo[id][Data_not_found] = true
 g_bUserInfo[id][Ignore_name_change] = true
 }
 
 g_bUserInfo[id][AccessUser] = true
 g_bUserInfo[id][Querying]   = false;
 g_bUserInfo[id][CheckOver]  = true;
}


public access_user(id)
{
 remove_user_flags(id)
 if (g_UserData[id][AccessInt])
 {
 set_user_flags(id, g_UserData[id][AccessInt])
 client_cmd(id, "echo ^"* %L^"", id, "PRIV_SET")
 }
 else
 {
 static defaccess[32]
 get_pcvar_string(p_default_access, defaccess, 31)
 if (!strlen(defaccess))
 {
 defaccess[0] = 'z'
 defaccess[1] = 0
 }
 
 set_user_flags(id, read_flags(defaccess))
 }
}


public check_auth_code(id)
{
 g_UserData[id][Login] = false;
 g_bUserInfo[id][Data_not_found] = false


 #if DEBUG
 server_print("111 check_auth_code name: %s - %s", g_UserData[id][Name], g_UserData[id][VGName])
 #endif
 
 if (!is_user_connected(id))
 {
 #if DEBUG
 server_print("check_auth_code is_user_connected:");
 #endif
 g_UserData[id][Login] = false
 g_bUserInfo[id][Data_not_found] = false
 g_UserData[id][PlayerType] = get_user_type_ex(id)
 user_error(id,MT_ERR_NOVG)
 return 0
 }
 
 // 如果是已经注册过的正版用户则提示登录
 if(g_bUserInfo[id][Steam])
 {
 #if DEBUG
 server_print("check_auth_code g_bUserInfo[id][Steam] true");
 #endif
 set_task(1.0, "task_check_steam_status", id + TASK_CHECK_QSTATUS)
 return 0
 }
 
 check_date()
 if(g_UserData[id][AuthSQL][0] == 0 ||
    g_UserData[id][AuthCodeNow][0] == 0 ||
    !g_bUserInfo[id][VGuard])
 {
 #if DEBUG
 server_print("check_auth_code err %s - %s - %s",g_UserData[id][AuthSQL],g_UserData[id][AuthCodeNow],g_bUserInfo[id][VGuard]);
 #endif
 
 g_UserData[id][Login] = false
 g_bUserInfo[id][Data_not_found] = false
 g_UserData[id][PlayerType] = get_user_type_ex(id)
 user_error(id,MT_ERR_PASS)
 return 0
 }
 
 #if DEBUG
 client_print(id,print_chat,"check_auth_code start - SQLPass:%s ClientPass:%s",g_UserData[id][AuthSQL],g_UserData[id][AuthCodeNow])
 server_print("check_auth_code start - SQLPass:%s ClientPass:%s",g_UserData[id][AuthSQL],g_UserData[id][AuthCodeNow])
 #endif
 if (equali(g_UserData[id][AuthSQL], g_UserData[id][AuthCodeNow]))
 {
 access_user(id)


 #if DEBUG
 server_print("check_auth_code type: %d",g_UserData[id][PlayerType]);
 #endif


 //client_cmd(id, "exec cspubsay.cfg")
 g_bUserInfo[id][Ignore_name_change] = false
 set_user_info(id, "name", g_UserData[id][ChsName])
 g_UserData[id][Login] = true;
 g_UserData[id][Login] = true;
 g_bUserInfo[id][CheckOver]  = true;
 g_bUserInfo[id][Data_not_found] = false
 g_UserData[id][PlayerType] = get_user_type_ex(id)
 client_color(id, id, "^x01[^x03%s^x01] ^x04登录成功(使用登陆器)", SERVER_NAME)
 
 #if DEBUG
 client_print(id, print_console, "you are login with VGuard Client.")
 #endif
 
 exec_login_forward(id)
 return 1
 }
 else
 {
 g_UserData[id][PlayerType] = get_user_type_ex(id)
 #if DEBUG
 client_print(id,print_chat,"check_auth_code end - user_error(id, MT_ERR_PASS)")
 server_print("check_auth_code end - user_error(id, MT_ERR_PASS)")
 #endif
 user_error(id, MT_ERR_PASS)
 }


 return 0
}


public client_connect(id) 
{
 data_clear(id, true)
 if (is_user_bot(id) || is_user_hltv(id))
 {
 return PLUGIN_HANDLED
 }


 // add command to queue
 server_cmd("dp_clientinfo %d", id)
 
 // make server to execute all queued commands
 server_exec()
 return PLUGIN_HANDLED
}


public client_disconnect(id)
{
 //new type = g_UserData[id][PlayerType]
 g_msg_index[id] = 0
 g_msg_type[id] = 0
 data_clear(id, false)
}


public client_putinserver(id)
{
 g_bUserInfo[id][Ignore_name_change] = false
 g_bUserInfo[id][Put_in_server] = true


 get_user_name(id, g_UserData[id][Name], MAX_NAME_LEN - 1)
 if (contain(g_UserData[id][Name], ERR_NAME_KEYWORD) != -1)
 {
 g_bUserInfo[id][Err_prefix] = true
 }
 
 #if DEBUG
 if(!is_user_bot(id))
 server_print("client_putinserver name: %s", g_UserData[id][Name])
 #endif
}


public client_authorized(id)
{
 if(!is_player(id))
 return
 
 data_clear(id, true)
 if(is_user_bot(id)/* || vg_getstatus(id) != 0*/)
 return
 
 g_bUserInfo[id][Steam] = true
 /*if(is_steam(id))
 {
 g_bUserInfo[id][Steam] = true
 //set_task(2.0, "task_check_steam_status", id + TASK_CHECK_QSTATUS)
 }*/
 
 // 为改此处来初始化客户端
 //if(is_player(id))
 // mi_guard_init_kernel(id)
 
 // 如果进来了30秒还没验证则强制登录
 //set_task(20.0,"task_delay_login", id + TASK_ID_CHECKLOGIN)
}


public task_delay_login(tid)
{
 new id = tid - TASK_ID_CHECKLOGIN
 if (!g_bUserInfo[id][CheckOver] || g_UserData[id][PlayerType] == MT_UNKNOW)
 {
 if(!task_exists(id + TASK_ID_LOGIN) && !g_bUserInfo[id][Querying]/* && vg_getstatus(id) == 0*/)
 {
 #if DEBUG
 server_print("fwd_Spawn task_delay_login")
 #endif
 set_task(30, "task_login", id + TASK_ID_LOGIN)
 }
 }
}


public cmd_test(id)
{
 new type = get_user_type(id)
 
 client_print(id,print_chat,"uid:%u", g_UserData[id][Index])


 client_print(id,print_chat,"%s %s type:%d [%s] access:%s version:%d",g_UserData[id][Name],g_UserData[id][ChsName],type,member[type],g_UserData[id][AccessStr],g_UserData[id][ClientVerion])


 //client_print(id,print_chat,"get_user_type(%d) g_bUserInfo[id][Err_prefix]:%d  g_bUserInfo[id][CheckOver]:%d  bot:%d vgstatus:%d.", 
 // id,g_bUserInfo[id][Err_prefix],g_UserData[id][CheckOver],is_user_bot(id), vg_getstatus(id))
 //server_print("get_user_type(%d) g_bUserInfo[id][Err_prefix]:%d  g_bUserInfo[id][CheckOver]:%d  bot:%d vgstatus:%d.", 
 // id,g_bUserInfo[id][Err_prefix],g_UserData[id][CheckOver],is_user_bot(id), vg_getstatus(id))
}


public plugin_init()
{
 register_plugin(PLUGIN, VERSION, AUTHOR)
 register_dictionary("admin.txt")
 
 // cvar
 pc_sql_host = register_cvar("rpgm_sql_host", "")
 pc_sql_user = register_cvar("rpgm_sql_user", "")
 pc_sql_pass = register_cvar("rpgm_sql_pass", "")
 pc_sql_db   = register_cvar("rpgm_sql_db", "")
 pc_log_srv  = register_cvar("amx_log_srvname", "SZ-1#")


 pc_vg_kick  = register_cvar("rpgm_sql_kick_unlongin", "0") // 0保留改名  1踢出  2保留仅M6
 p_default_access = register_cvar("amx_default_access", "z")


 // client command
 register_clcmd("say test", "cmd_test")
 register_event( "TeamInfo", "fwd_jointeam", "a", "2!UNASSIGNED")
 register_forward(FM_ClientUserInfoChanged, "fwd_ClientUserInfoChanged", 0)
 
 #if OPEN_STEAM
 register_concmd("enter_password", "cmd_enter_password")
 register_concmd("reg_enter_password", "cmd_reg_enter_password")
 register_concmd("reg_enter_password_again", "cmd_reg_enter_password_again")
 #endif // OPEN_STEAM
 
 RegisterHam(Ham_Spawn, "player", "fwd_Spawn", 1)
 
 // log file
 date(g_year, g_month, g_day)
 formatex(g_str_date, 31, "%04d-%02d-%02d", g_year, g_month, g_day)
 //server_print("today: %s", g_str_date)
 
 format(g_log_Error, 255, "MTError%04d%02d%02d.log", g_year, g_month, g_day)
 format(g_log_Login, 255, "MTLogin%04d%02d%02d.log", g_year, g_month, g_day)
 format(g_log_Shop,  255, "MTShop%04d%02d%02d.log",  g_year, g_month, g_day)
 
 // forward
 // id, uid, exp, type
 g_forward = CreateMultiForward("client_login", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL)
 if(g_forward == -1)
 server_print("Error creating forward")
 
 mt_init_config()
}


public plugin_end()
{
 g_mapchange_started = true
 if (g_sql_tuple != Empty_Handle)
 {
 SQL_FreeHandle(g_sql_tuple);
 g_sql_tuple = Empty_Handle;
 }
}





VSLogin.inc
複製程式
#if defined _mt_login_included
    #endinput
#endif


#define _mt_login_included


#pragma reqlib "mt_login"


////////////////////////////////////////////////////////////
//
// VIP类型
//
enum
{
 MT_UNKNOW = 0, // 未检查
 MT_UNREG, // 未注册
 MT_NONSTEAM, // 会员
}


////////////////////////////////////////////////////////////
//
// 玩家数据库资料
//


// 获取玩家数字编号
native get_user_uid(id)


// 获取玩家VIP类型
native get_user_type(id)


// 获取玩家英文名
native get_user_engname(id, engname[], len)


// 获取玩家中文名
native get_user_chsname(id, chsname[], len)


// 获取玩家qq
native get_user_qq(id, qq[], len)


// 获取玩家签名
native get_user_signature(id, signature[], len)


// 获取玩家权限字母a-z
native get_vip_flag(id, flag[], len)


// 获取玩家权限到期时间
native get_exp_date(id, expdate[], len)


// 获取玩家注册时间
native get_reg_date(id, regdate[], len)






////////////////////////////////////////////////////////////
//
// MySQL数据库 (以便别的插件调用)
//


// 获取数据库地址
native get_sql_host(hst[], len)


// 获取数据库用户名
native get_sql_user(usr[], len)


// 获取数据库密码
native get_sql_pass(pwd[], len)


// 获取数据库名
native get_sql_db(dbname[], len)


// 添加管理日志
native log_admin_mysql(string[])




////////////////////////////////////////////////////////////
//
// 回调函数 (当玩家登录或注册成功时会触发)
//


// 玩家登录事件
forward client_login(id, uid, exp, type)


/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ ansicpg936\\ deff0{\\ fonttbl{\\ f0\\ fnil\\ fcharset134 Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang2052\\ f0\\ fs16 \n\\ par }
*/



server.cfg
複製程式
// MySQL参数
rpgm_sql_host "127.0.0.1"
rpgm_sql_user  "root"
rpgm_sql_pass  "123456"
rpgm_sql_db  "hlds_vguard"



hlds_vguard.sql
複製程式
-- ************************************************************
--
-- close fk
--
-- skip




-- MySQL dump 10.13  Distrib 5.7.35, for Linux (x86_64)
--
-- Host: 100.121.194.27    Database: hlds_vguard
-- ------------------------------------------------------
-- Server version 5.5.45-cdb20180926-log


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;


--
-- Table structure for table `mt_adminlog`
--


DROP TABLE IF EXISTS `mt_adminlog`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `mt_adminlog` (
  `log_time` varchar(25) NOT NULL DEFAULT '',
  `index` int(64) NOT NULL AUTO_INCREMENT,
  `log_server` varchar(32) NOT NULL DEFAULT '',
  `log_msg` varchar(300) NOT NULL DEFAULT '',
  PRIMARY KEY (`index`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;


/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;


-- Dump completed on 2023-10-08  0:21:11
-- ************************************************************
--
-- close fk
--
-- skip




-- MySQL dump 10.13  Distrib 5.7.35, for Linux (x86_64)
--
-- Host: 100.121.194.27    Database: hlds_vguard
-- ------------------------------------------------------
-- Server version 5.5.45-cdb20180926-log


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;


--
-- Table structure for table `mt_reg`
--


DROP TABLE IF EXISTS `mt_reg`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `mt_reg` (
  `name` varchar(31) CHARACTER SET utf8 NOT NULL,
  `chsname` char(33) CHARACTER SET utf8 DEFAULT NULL,
  `password` char(32) DEFAULT NULL,
  `password2` varchar(32) DEFAULT NULL,
  `access` char(26) DEFAULT NULL,
  `exp_date` char(32) DEFAULT NULL,
  `index` int(8) unsigned NOT NULL AUTO_INCREMENT,
  `xp` int(8) unsigned DEFAULT '0',
  `regdate` char(10) DEFAULT NULL,
  `lastlogin` char(10) DEFAULT NULL,
  `timestamp` int(12) DEFAULT '0',
  `signature` varchar(64) CHARACTER SET utf8 DEFAULT '',
  `QQ` varchar(33) DEFAULT NULL,
  `ip` varchar(24) DEFAULT NULL,
  `modifyed` char(1) DEFAULT '0',
  `picture` char(32) DEFAULT NULL,
  PRIMARY KEY (`index`),
  UNIQUE KEY `name` (`name`),
  UNIQUE KEY `chsname` (`chsname`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;


/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;


-- Dump completed on 2023-10-08  0:21:11
-- ************************************************************
--
-- close fk
--
-- skip




-- MySQL dump 10.13  Distrib 5.7.35, for Linux (x86_64)
--
-- Host: 100.121.194.27    Database: hlds_vguard
-- ------------------------------------------------------
-- Server version 5.5.45-cdb20180926-log


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;


--
-- Table structure for table `mt_vguard_cheat`
--


DROP TABLE IF EXISTS `mt_vguard_cheat`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `mt_vguard_cheat` (
  `index` int(8) unsigned NOT NULL AUTO_INCREMENT,
  `log_time` varchar(24) CHARACTER SET utf8 NOT NULL,
  `log_server` varchar(33) CHARACTER SET utf8 DEFAULT NULL,
  `log_uid` int(8) unsigned DEFAULT NULL,
  `log_name` varchar(33) CHARACTER SET utf8 DEFAULT NULL,
  `log_ip` varchar(24) CHARACTER SET utf8 DEFAULT NULL,
  `log_type` varchar(33) CHARACTER SET utf8 DEFAULT NULL,
  `log_hard` varchar(36) CHARACTER SET utf8 DEFAULT NULL,
  `log_module` varchar(64) CHARACTER SET utf8 DEFAULT NULL,
  `log_crc` varchar(32) CHARACTER SET utf8 DEFAULT NULL,
  `log_size` int(4) unsigned DEFAULT '0',
  PRIMARY KEY (`index`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;


/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;


-- Dump completed on 2023-10-08  0:21:11


本帖包含附件
zip AMXX自动注册登录+排名系统2023.zip   (2023-10-08 01:05 / 647 KB)   下載次數:21


[ 此文章被wangningyu在2023-10-08 14:14重新編輯 ]

此文章被評分,最近評分記錄
財富:300 (by amore12)



One Code , One Dream !
獻花 x0 回到頂端 [樓 主] From:美國ATT用戶 | Posted:2023-10-08 01:05 |
大几把
個人文章 個人相簿 個人日記 個人地圖
小人物
級別: 小人物 該用戶目前不上站
推文 x0 鮮花 x1
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

辛苦了


獻花 x0 回到頂端 [1 樓] From:IANA保留地址 | Posted:2023-10-11 12:12 |
songliujie
個人文章 個人相簿 個人日記 個人地圖
路人甲
級別: 路人甲 該用戶目前不上站
推文 x0 鮮花 x0
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片

辛苦了 表情


獻花 x0 回到頂端 [2 樓] From:IANA保留地址 | Posted:2024-01-06 01:11 |

首頁  發表文章 發表投票 回覆文章
Powered by PHPWind v1.3.6
Copyright © 2003-04 PHPWind
Processed in 0.050334 second(s),query:16 Gzip disabled
本站由 瀛睿律師事務所 擔任常年法律顧問 | 免責聲明 | 本網站已依台灣網站內容分級規定處理 | 連絡我們 | 訪客留言