添加示例项目
This commit is contained in:
290
示例项目/NPC商店限购/NPC商店限购.nut
Normal file
290
示例项目/NPC商店限购/NPC商店限购.nut
Normal file
@@ -0,0 +1,290 @@
|
||||
g_ShopLimitCache <- {};
|
||||
|
||||
class _Shop_Limit_Bynangua {
|
||||
function get_trade_time() {
|
||||
local currentDate = date()
|
||||
local year = currentDate.year
|
||||
local month = currentDate.month + 1
|
||||
local day = currentDate.day
|
||||
local hour = currentDate.hour
|
||||
local minute = currentDate.min
|
||||
local second = currentDate.sec
|
||||
return format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
|
||||
}
|
||||
|
||||
// 计算下个月的1号早上6点
|
||||
function GetFirstOfNextMonth() {
|
||||
local currentDate = date()
|
||||
local year = currentDate.year
|
||||
local month = currentDate.month + 2 // +2是因为month是从0开始的,且要算下个月
|
||||
local day = 1
|
||||
local hour = 6
|
||||
local minute = 0
|
||||
local second = 0
|
||||
return format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
|
||||
}
|
||||
|
||||
// 计算下周一早上6点
|
||||
function GetNextMonday() {
|
||||
local currentDate = date()
|
||||
local day = currentDate.wday // 0是周日,1-6是周一到周六
|
||||
local diff = (day == 0) ? 1 : (8 - day)
|
||||
currentDate.day += diff
|
||||
local year = currentDate.year
|
||||
local month = currentDate.month + 1
|
||||
local day = currentDate.day
|
||||
local hour = 6
|
||||
local minute = 0
|
||||
local second = 0
|
||||
return format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
|
||||
}
|
||||
|
||||
// 计算第二天早上6点
|
||||
function GetSixAMNextDay() {
|
||||
local currentDate = date()
|
||||
local year = currentDate.year
|
||||
local month = currentDate.month + 1
|
||||
local day = currentDate.day + 1
|
||||
local hour = 6
|
||||
local minute = 0
|
||||
local second = 0
|
||||
return format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
|
||||
}
|
||||
|
||||
// 获取刷新时间
|
||||
function GetRefreshTime(refresh_month, refresh_weeks, refresh_days) {
|
||||
if (refresh_month == 1) {
|
||||
return GetFirstOfNextMonth()
|
||||
} else if (refresh_weeks == 1) {
|
||||
return GetNextMonday()
|
||||
} else if (refresh_days == 1) {
|
||||
return GetSixAMNextDay()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function HandlePurchase(SUser, item_id, item_shop_id, item_info, item_cnt) {
|
||||
local charac_no = SUser.GetCID();
|
||||
local cache_key = charac_no + "_" + item_id + "_" + item_shop_id;
|
||||
|
||||
if (g_ShopLimitCache.rawin(cache_key)) {
|
||||
local cache_data = g_ShopLimitCache[cache_key];
|
||||
local buy_count = cache_data.buy_count;
|
||||
local refresh_time = cache_data.refresh_time;
|
||||
local current_time = get_trade_time();
|
||||
|
||||
if (current_time >= refresh_time) {
|
||||
if (item_cnt > item_info[1]) {
|
||||
SUser.SendNotiPacketMessage("购买失败,可购买数量剩余 " + item_info[1] + " 个", 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
local new_refresh_time = GetRefreshTime(item_info[2], item_info[3], item_info[4]);
|
||||
g_ShopLimitCache[cache_key] <- {
|
||||
buy_count = item_cnt,
|
||||
refresh_time = new_refresh_time
|
||||
};
|
||||
|
||||
updateDatabaseAsync(charac_no, item_id, item_shop_id, item_cnt, new_refresh_time);
|
||||
} else {
|
||||
local remaining = item_info[1] - buy_count;
|
||||
if (item_cnt > remaining) {
|
||||
if (remaining == 0) {
|
||||
local refresh_msg = "";
|
||||
if (item_info[2] == 1) { // 月刷新
|
||||
refresh_msg = "每月一日上午六点";
|
||||
} else if (item_info[3] == 1) { // 周刷新
|
||||
refresh_msg = "每周一日上午六点";
|
||||
} else if (item_info[4] == 1) { // 日刷新
|
||||
refresh_msg = "每日一日上午六点";
|
||||
}
|
||||
SUser.SendNotiPacketMessage("当前商品已售罄,将在" + refresh_msg + "刷新", 8);
|
||||
} else {
|
||||
SUser.SendNotiPacketMessage("购买失败,可购买数量剩余 " + remaining + " 个", 8);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
g_ShopLimitCache[cache_key] <- {
|
||||
buy_count = buy_count + item_cnt,
|
||||
refresh_time = refresh_time
|
||||
};
|
||||
|
||||
updateDatabaseAsync(charac_no, item_id, item_shop_id, buy_count + item_cnt, refresh_time);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local query = "SELECT id, charac_no, item_id, buy_count, item_shop, refresh_time FROM DP_S.restrict_npc_shop_buy WHERE charac_no=" + charac_no + " AND item_id=" + item_id + " AND item_shop=" + item_shop_id;
|
||||
local column_type_list = ["int", "int", "int", "int", "int", "string"];
|
||||
local result = SqlObj.Select(query, column_type_list);
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
|
||||
if (result.len() == 0) {
|
||||
if (item_cnt > item_info[1]) {
|
||||
SUser.SendNotiPacketMessage("购买失败,可购买数量剩余 " + item_info[1] + " 个", 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
local refresh_time = GetRefreshTime(item_info[2], item_info[3], item_info[4]);
|
||||
|
||||
g_ShopLimitCache[cache_key] <- {
|
||||
buy_count = item_cnt,
|
||||
refresh_time = refresh_time
|
||||
};
|
||||
|
||||
updateDatabaseAsync(charac_no, item_id, item_shop_id, item_cnt, refresh_time);
|
||||
} else {
|
||||
local buy_count = result[0][3];
|
||||
local refresh_time = result[0][5];
|
||||
local current_time = get_trade_time();
|
||||
|
||||
g_ShopLimitCache[cache_key] <- {
|
||||
buy_count = buy_count,
|
||||
refresh_time = refresh_time
|
||||
};
|
||||
|
||||
if (current_time >= refresh_time) {
|
||||
if (item_cnt > item_info[1]) {
|
||||
SUser.SendNotiPacketMessage("购买失败,可购买数量剩余 " + item_info[1] + " 个", 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
local new_refresh_time = GetRefreshTime(item_info[2], item_info[3], item_info[4]);
|
||||
g_ShopLimitCache[cache_key] <- {
|
||||
buy_count = item_cnt,
|
||||
refresh_time = new_refresh_time
|
||||
};
|
||||
|
||||
updateDatabaseAsync(charac_no, item_id, item_shop_id, item_cnt, new_refresh_time);
|
||||
} else {
|
||||
local remaining = item_info[1] - buy_count;
|
||||
if (item_cnt > remaining) {
|
||||
if (remaining == 0) {
|
||||
local refresh_msg = "";
|
||||
if (item_info[2] == 1) { // 月刷新
|
||||
refresh_msg = "每月一日上午六点";
|
||||
} else if (item_info[3] == 1) { // 周刷新
|
||||
refresh_msg = "每周一日上午六点";
|
||||
} else if (item_info[4] == 1) { // 日刷新
|
||||
refresh_msg = "每日一日上午六点";
|
||||
}
|
||||
SUser.SendNotiPacketMessage("当前商品已售罄,将在" + refresh_msg + "刷新", 8);
|
||||
} else {
|
||||
SUser.SendNotiPacketMessage("购买失败,可购买数量剩余 " + remaining + " 个", 8);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
g_ShopLimitCache[cache_key] <- {
|
||||
buy_count = buy_count + item_cnt,
|
||||
refresh_time = refresh_time
|
||||
};
|
||||
|
||||
updateDatabaseAsync(charac_no, item_id, item_shop_id, buy_count + item_cnt, refresh_time);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新缓存到数据库
|
||||
function updateDatabaseAsync(charac_no, item_id, item_shop_id, buy_count, refresh_time) {
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
// 使用 ON DUPLICATE KEY UPDATE 来更新已存在的记录
|
||||
local query = "INSERT INTO DP_S.restrict_npc_shop_buy (charac_no, item_id, buy_count, item_shop, refresh_time) " +
|
||||
"VALUES (" + charac_no + ", " + item_id + ", " + buy_count + ", " + item_shop_id + ", '" + refresh_time + "') " +
|
||||
"ON DUPLICATE KEY UPDATE buy_count = VALUES(buy_count), refresh_time = VALUES(refresh_time)";
|
||||
SqlObj.Select(query, []);
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
}
|
||||
|
||||
// 服务器启动时加载缓存
|
||||
function loadShopLimitCache() {
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
local query = "SELECT charac_no, item_id, item_shop, buy_count, refresh_time FROM DP_S.restrict_npc_shop_buy";
|
||||
local column_type_list = ["int", "int", "int", "int", "string"];
|
||||
local result = SqlObj.Select(query, column_type_list);
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
|
||||
foreach(row in result) {
|
||||
local cache_key = row[0] + "_" + row[1] + "_" + row[2];
|
||||
g_ShopLimitCache[cache_key] <- {
|
||||
buy_count = row[3],
|
||||
refresh_time = row[4]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 服务器关闭时保存缓存
|
||||
Cb_Server_Close_Enter_Func.ShopLimitSave <- function(arg) {
|
||||
foreach(cache_key, data in g_ShopLimitCache) {
|
||||
local parts = split(cache_key, "_");
|
||||
local charac_no = parts[0].tointeger();
|
||||
local item_id = parts[1].tointeger();
|
||||
local item_shop = parts[2].tointeger();
|
||||
updateDatabaseAsync(charac_no, item_id, item_shop, data.buy_count, data.refresh_time);
|
||||
}
|
||||
g_ShopLimitCache <- {};
|
||||
}
|
||||
|
||||
function _Dps_Shop_Limit_Main_() {
|
||||
CreateShopLimitTable();
|
||||
loadShopLimitCache();
|
||||
Cb_BuyItem_check_error_Leave_Func.Shop_Limit_ByNangua <- function(args) {
|
||||
local Config = GlobalConfig.Get("NPC商店限购配置_Nangua.json");
|
||||
local shop_limit_config = Config["商店限购配置"];
|
||||
local is_buy = false;
|
||||
local SUser = User(args[1]);
|
||||
local msg_base = args[2];
|
||||
local Item_id = NativePointer(msg_base).add(13).readU32();
|
||||
local item_shop = NativePointer(msg_base).add(21).readU32();
|
||||
local item_cnt = NativePointer(msg_base).add(17).readU32();
|
||||
local item_shop_id = item_shop.tostring();
|
||||
if (item_shop_id in shop_limit_config) {
|
||||
local items_list = shop_limit_config[item_shop_id];
|
||||
foreach(item_info in items_list) {
|
||||
if (item_info[0] == Item_id) {
|
||||
is_buy = _Shop_Limit_Bynangua.HandlePurchase(SUser, Item_id, item_shop, item_info, item_cnt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_buy) {
|
||||
return 19;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function CreateShopLimitTable() {
|
||||
local Config = GlobalConfig.Get("NPC商店限购配置_Nangua.json");
|
||||
local PoolObj = MysqlPool.GetInstance();
|
||||
local Ip = Config["数据库IP 不是外置数据库不要更改"];
|
||||
local Port = Config["数据库端口 不懂不要更改"];
|
||||
local DbName = Config["数据库用户名 本地用户名不懂不要更改"];
|
||||
local Password = Config["数据库密码 本地密码不懂不要更改"];
|
||||
|
||||
PoolObj.SetBaseConfiguration(Ip, Port, DbName, Password);
|
||||
PoolObj.PoolSize = 10;
|
||||
PoolObj.Init();
|
||||
|
||||
// 建库建表SQL
|
||||
local CreateSql1 = "create database if not exists DP_S default charset utf8;";
|
||||
local CreateSql2 = "CREATE TABLE IF NOT EXISTS DP_S.restrict_npc_shop_buy (" +
|
||||
"id int(11) AUTO_INCREMENT, " +
|
||||
"charac_no int(11) NOT NULL, " +
|
||||
"item_id int(11) NOT NULL, " +
|
||||
"buy_count int(11) NOT NULL, " +
|
||||
"item_shop int(11) NOT NULL, " +
|
||||
"refresh_time varchar(255) NOT NULL, " +
|
||||
"PRIMARY KEY (id), " +
|
||||
"UNIQUE KEY unique_purchase (charac_no, item_id, item_shop)" +
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
|
||||
|
||||
// 执行SQL
|
||||
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
||||
SqlObj.Exec_Sql(CreateSql1);
|
||||
SqlObj.Exec_Sql(CreateSql2);
|
||||
MysqlPool.GetInstance().PutConnect(SqlObj);
|
||||
}
|
||||
Reference in New Issue
Block a user