mirror of
https://github.com/oshima-studios/OshimaGameModule.git
synced 2026-06-04 19:42:13 +00:00
添加支持率
This commit is contained in:
parent
187630233b
commit
226159bb53
@ -125,6 +125,16 @@ namespace Oshima.FunGame.WebAPI.Model
|
|||||||
/// 支持的投注选项类型(常规包含 Team1Win/Team2Win,总决赛增加 Score)
|
/// 支持的投注选项类型(常规包含 Team1Win/Team2Win,总决赛增加 Score)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<BetOptionType> AvailableOptions { get; set; } = [BetOptionType.Team1Win, BetOptionType.Team2Win];
|
public List<BetOptionType> AvailableOptions { get; set; } = [BetOptionType.Team1Win, BetOptionType.Team2Win];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 队伍1胜赔率,默认2.5
|
||||||
|
/// </summary>
|
||||||
|
public decimal Team1WinOdds { get; set; } = 2.50m;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 队伍2胜赔率,默认2.5
|
||||||
|
/// </summary>
|
||||||
|
public decimal Team2WinOdds { get; set; } = 2.50m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -208,5 +218,11 @@ namespace Oshima.FunGame.WebAPI.Model
|
|||||||
|
|
||||||
[JsonPropertyName("available_options")]
|
[JsonPropertyName("available_options")]
|
||||||
public string AvailableOptions { get; set; } = "team1_win,team2_win";
|
public string AvailableOptions { get; set; } = "team1_win,team2_win";
|
||||||
|
|
||||||
|
[JsonPropertyName("team1_win_odds")]
|
||||||
|
public decimal? Team1WinOdds { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("team2_win_odds")]
|
||||||
|
public decimal? Team2WinOdds { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,6 +147,8 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
string available = row["available_options"]?.ToString() ?? "[]";
|
string available = row["available_options"]?.ToString() ?? "[]";
|
||||||
string result = row["result"] != DBNull.Value ? row["result"].ToString() ?? "" : "";
|
string result = row["result"] != DBNull.Value ? row["result"].ToString() ?? "" : "";
|
||||||
long winner = row["winner"] != DBNull.Value ? Convert.ToInt64(row["winner"]) : 0;
|
long winner = row["winner"] != DBNull.Value ? Convert.ToInt64(row["winner"]) : 0;
|
||||||
|
decimal team1Odds = Convert.ToDecimal(row["team1_win_odds"]);
|
||||||
|
decimal team2Odds = Convert.ToDecimal(row["team2_win_odds"]);
|
||||||
|
|
||||||
string eventName = "";
|
string eventName = "";
|
||||||
sql.Parameters["@eid"] = eventId;
|
sql.Parameters["@eid"] = eventId;
|
||||||
@ -172,9 +174,9 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
if (status == 0)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
sb.AppendLine($"可用选项:");
|
sb.AppendLine($"可用选项:");
|
||||||
if (available.Contains("team1_win")) sb.AppendLine($" - {t1}胜 (x 2.5)");
|
if (available.Contains("team1_win")) sb.AppendLine($" - {t1}胜 (x {team1Odds})");
|
||||||
if (available.Contains("team2_win")) sb.AppendLine($" - {t2}胜 (x 2.5)");
|
if (available.Contains("team2_win")) sb.AppendLine($" - {t2}胜 (x {team2Odds})");
|
||||||
if (available.Contains("score")) sb.AppendLine($" - 精确比分 (x 3.5)");
|
if (available.Contains("score")) sb.AppendLine($" - 精确比分 (x 4)");
|
||||||
if (available.Contains("mvp")) sb.AppendLine($" - 赛事MVP (x 3.5)");
|
if (available.Contains("mvp")) sb.AppendLine($" - 赛事MVP (x 3.5)");
|
||||||
}
|
}
|
||||||
else if (status == 2)
|
else if (status == 2)
|
||||||
@ -308,6 +310,8 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
sql.ExecuteDataSet("SELECT * FROM csbetting_bet_records WHERE match_id=@mid AND is_settled=0");
|
sql.ExecuteDataSet("SELECT * FROM csbetting_bet_records WHERE match_id=@mid AND is_settled=0");
|
||||||
if (sql.Success && sql.DataSet.Tables[0].Rows.Count > 0)
|
if (sql.Success && sql.DataSet.Tables[0].Rows.Count > 0)
|
||||||
{
|
{
|
||||||
|
decimal team1Odds = Convert.ToDecimal(row["team1_win_odds"]);
|
||||||
|
decimal team2Odds = Convert.ToDecimal(row["team2_win_odds"]);
|
||||||
foreach (DataRow bet in sql.DataSet.Tables[0].Rows)
|
foreach (DataRow bet in sql.DataSet.Tables[0].Rows)
|
||||||
{
|
{
|
||||||
long betId = Convert.ToInt64(bet["id"]);
|
long betId = Convert.ToInt64(bet["id"]);
|
||||||
@ -325,7 +329,14 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
string note = "未中奖";
|
string note = "未中奖";
|
||||||
if (win)
|
if (win)
|
||||||
{
|
{
|
||||||
double odds = otype switch { 2 or 3 => 3.5, _ => 2.5 };
|
double odds = otype switch
|
||||||
|
{
|
||||||
|
1 => (double)team1Odds,
|
||||||
|
2 => (double)team2Odds,
|
||||||
|
3 => 4,
|
||||||
|
4 => 3.5,
|
||||||
|
_ => 2.5
|
||||||
|
};
|
||||||
payout = (long)(amount * odds);
|
payout = (long)(amount * odds);
|
||||||
note = "中奖";
|
note = "中奖";
|
||||||
}
|
}
|
||||||
@ -559,7 +570,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建比赛
|
// 创建比赛
|
||||||
public static bool CreateMatch(int eventId, string team1Name, string team2Name, string stage, DateTime startTime, DateTime betDeadline, string availableOptions, out string error, out long? newMatchId)
|
public static bool CreateMatch(int eventId, string team1Name, string team2Name, string stage, DateTime startTime, DateTime betDeadline, string availableOptions, decimal? team1WinOdds, decimal? team2WinOdds, out string error, out long? newMatchId)
|
||||||
{
|
{
|
||||||
error = "";
|
error = "";
|
||||||
newMatchId = null;
|
newMatchId = null;
|
||||||
@ -581,6 +592,22 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
.Where(s => s.Length > 0)];
|
.Where(s => s.Length > 0)];
|
||||||
string optionsJson = System.Text.Json.JsonSerializer.Serialize(options);
|
string optionsJson = System.Text.Json.JsonSerializer.Serialize(options);
|
||||||
|
|
||||||
|
// 如果比赛包含比分或 MVP 选项,不允许自定义猜胜者赔率
|
||||||
|
bool hasSpecialOption = options.Contains("score") || options.Contains("mvp");
|
||||||
|
if ((team1WinOdds.HasValue || team2WinOdds.HasValue) && hasSpecialOption)
|
||||||
|
{
|
||||||
|
error = "比赛包含比分或MVP选项时,不能自定义猜胜者赔率。";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
decimal t1Odds = team1WinOdds ?? 2.50m;
|
||||||
|
decimal t2Odds = team2WinOdds ?? 2.50m;
|
||||||
|
if (t1Odds <= 0 || t2Odds <= 0)
|
||||||
|
{
|
||||||
|
error = "赔率必须大于0。";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
sql.Parameters["@eid"] = eventId;
|
sql.Parameters["@eid"] = eventId;
|
||||||
sql.Parameters["@t1"] = team1Name;
|
sql.Parameters["@t1"] = team1Name;
|
||||||
sql.Parameters["@t2"] = team2Name;
|
sql.Parameters["@t2"] = team2Name;
|
||||||
@ -588,9 +615,11 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
sql.Parameters["@start"] = startTime;
|
sql.Parameters["@start"] = startTime;
|
||||||
sql.Parameters["@deadline"] = betDeadline;
|
sql.Parameters["@deadline"] = betDeadline;
|
||||||
sql.Parameters["@opts"] = optionsJson;
|
sql.Parameters["@opts"] = optionsJson;
|
||||||
|
sql.Parameters["@t1_odds"] = t1Odds;
|
||||||
|
sql.Parameters["@t2_odds"] = t2Odds;
|
||||||
sql.Execute(@"INSERT INTO csbetting_matches
|
sql.Execute(@"INSERT INTO csbetting_matches
|
||||||
(event_id, team1_name, team2_name, stage, start_time, bet_deadline, available_options, status)
|
(event_id, team1_name, team2_name, stage, start_time, bet_deadline, available_options, team1_win_odds, team2_win_odds, status)
|
||||||
VALUES (@eid, @t1, @t2, @stage, @start, @deadline, @opts, 0)");
|
VALUES (@eid, @t1, @t2, @stage, @start, @deadline, @opts, @t1_odds, @t2_odds, 0)");
|
||||||
|
|
||||||
if (sql.Success)
|
if (sql.Success)
|
||||||
{
|
{
|
||||||
@ -603,5 +632,48 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
error = "数据库连接失败。";
|
error = "数据库连接失败。";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 管理员提前结束竞猜(将未开始比赛标记为进行中)
|
||||||
|
/// </summary>
|
||||||
|
public static bool CloseBetting(int matchId, out string message)
|
||||||
|
{
|
||||||
|
using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper();
|
||||||
|
if (sql == null)
|
||||||
|
{
|
||||||
|
message = "数据库连接失败。";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateStatuses(sql);
|
||||||
|
|
||||||
|
sql.Parameters["@mid"] = matchId;
|
||||||
|
sql.ExecuteDataSet("SELECT status, team1_name, team2_name FROM csbetting_matches WHERE id = @mid");
|
||||||
|
if (!sql.Success || sql.DataSet.Tables[0].Rows.Count == 0)
|
||||||
|
{
|
||||||
|
message = "比赛不存在。";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int status = Convert.ToInt32(sql.DataSet.Tables[0].Rows[0]["status"]);
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
message = "该比赛已开始或已结束,无需关闭投注。";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql.Execute("UPDATE csbetting_matches SET status = 1 WHERE id = @mid");
|
||||||
|
if (sql.Success)
|
||||||
|
{
|
||||||
|
string t1 = sql.DataSet.Tables[0].Rows[0]["team1_name"].ToString() ?? "";
|
||||||
|
string t2 = sql.DataSet.Tables[0].Rows[0]["team2_name"].ToString() ?? "";
|
||||||
|
string matchlabel = $"{t1} vs {t2}".CreateCmdInput($"比赛详情 {matchId}");
|
||||||
|
message = $"[比赛{matchId}] {matchlabel} 的竞猜已提前关闭。";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
message = "更新比赛状态失败。";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,3 +60,10 @@ CREATE TABLE IF NOT EXISTS `csbetting_matches` (
|
|||||||
KEY `idx_start_time` (`start_time`),
|
KEY `idx_start_time` (`start_time`),
|
||||||
CONSTRAINT `fk_matches_event` FOREIGN KEY (`event_id`) REFERENCES `csbetting_events` (`id`) ON DELETE CASCADE
|
CONSTRAINT `fk_matches_event` FOREIGN KEY (`event_id`) REFERENCES `csbetting_events` (`id`) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='CS比赛表';
|
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='CS比赛表';
|
||||||
|
|
||||||
|
-- PATCH
|
||||||
|
|
||||||
|
-- 为比赛表添加猜胜者赔率字段
|
||||||
|
ALTER TABLE `csbetting_matches`
|
||||||
|
ADD COLUMN `team1_win_odds` DECIMAL(5,2) NOT NULL DEFAULT 2.50 COMMENT '队伍1胜赔率' AFTER `available_options`,
|
||||||
|
ADD COLUMN `team2_win_odds` DECIMAL(5,2) NOT NULL DEFAULT 2.50 COMMENT '队伍2胜赔率' AFTER `team1_win_odds`;
|
||||||
|
|||||||
@ -94,7 +94,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
|||||||
// 校验金额
|
// 校验金额
|
||||||
if (amount < 1000)
|
if (amount < 1000)
|
||||||
{
|
{
|
||||||
md.Content = "最低投注额为 1000 {General.GameplayEquilibriumConstant.InGameCurrency}。";
|
md.Content = $"最低投注额为 1000 {General.GameplayEquilibriumConstant.InGameCurrency}。";
|
||||||
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
|
FunGameService.SetUserConfigButNotRelease(uid, pc, user);
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CSBettingService.CreateMatch(request.EventId, request.Team1Name, request.Team2Name, request.Stage,
|
if (CSBettingService.CreateMatch(request.EventId, request.Team1Name, request.Team2Name, request.Stage,
|
||||||
request.StartTime, request.BetDeadline, request.AvailableOptions, out string error, out long? newId))
|
request.StartTime, request.BetDeadline, request.AvailableOptions, request.Team1WinOdds, request.Team2WinOdds, out string error, out long? newId))
|
||||||
{
|
{
|
||||||
md.Content = $"比赛创建成功!新比赛ID:{newId}";
|
md.Content = $"比赛创建成功!新比赛ID:{newId}";
|
||||||
}
|
}
|
||||||
@ -269,5 +269,32 @@ namespace Oshima.FunGame.WebAPI.Controllers
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("close-betting")]
|
||||||
|
public BotReply CloseBetting([FromQuery] long uid, [FromQuery] int matchId)
|
||||||
|
{
|
||||||
|
MarkdownMessage md = new() { Content = busy };
|
||||||
|
BotReply reply = new() { Markdown = md };
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!FunGameConstant.UserIdAndUsername.TryGetValue(uid, out User? admin) || (!admin.IsAdmin && !admin.IsOperator))
|
||||||
|
{
|
||||||
|
md.Content = "你没有权限执行此操作。";
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CSBettingService.CloseBetting(matchId, out string msg))
|
||||||
|
{
|
||||||
|
md.Content = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.LogError(e, "CloseBetting 异常");
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,6 +143,10 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
.AppendButtons(2,
|
.AppendButtons(2,
|
||||||
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"),
|
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"),
|
||||||
Button.CreateCmdButton("📋 赛事列表", "赛事列表"));
|
Button.CreateCmdButton("📋 赛事列表", "赛事列表"));
|
||||||
|
if (reply.Markdown?.Content?.Contains("创建存档") ?? false)
|
||||||
|
{
|
||||||
|
reply.Keyboard.AppendButtons(2, Button.CreateCmdButton("⚙️ 创建存档", "创建存档"));
|
||||||
|
}
|
||||||
await SendAsync(e, "CS赛事竞猜", reply);
|
await SendAsync(e, "CS赛事竞猜", reply);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -268,7 +272,8 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
|
|
||||||
// 指令:创建比赛 <赛事ID> <队伍1> <队伍2> <阶段> <开始时间> <投注截止时间> [选项列表(逗号分隔)]
|
// 指令:创建比赛 <赛事ID> <队伍1> <队伍2> <阶段> <开始时间> <投注截止时间> [选项列表(逗号分隔)]
|
||||||
// 示例:创建比赛 1 NAVI FaZe Quarter-final 2026-03-05 14:00 2026-03-05 13:55
|
// 示例:创建比赛 1 NAVI FaZe Quarter-final 2026-03-05 14:00 2026-03-05 13:55
|
||||||
// 示例:创建比赛 1 G2 Vitality Semi-final 2026-04-02 18:00 2026-04-02 17:55 team1_win,team2_win,score
|
// 示例:创建比赛 1 G2 Vitality Semi-final 2026-04-02 18:00 2026-04-02 17:55 team1_win,team2_win
|
||||||
|
// 示例:创建比赛 1 G2 Vitality Semi-final 2026-04-02 18:00 2026-04-02 17:55 team1_win=2.5 team2_win=2.5 team1_win,team2_win
|
||||||
if (e.Detail.StartsWith("创建比赛"))
|
if (e.Detail.StartsWith("创建比赛"))
|
||||||
{
|
{
|
||||||
e.UseNotice = false;
|
e.UseNotice = false;
|
||||||
@ -286,7 +291,7 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
"格式:创建比赛 <赛事ID> <队伍1> <队伍2> <阶段> <开始时间> <投注截止时间> [选项列表(逗号分隔)]\r\n" +
|
"格式:创建比赛 <赛事ID> <队伍1> <队伍2> <阶段> <开始时间> <投注截止时间> [选项列表(逗号分隔)]\r\n" +
|
||||||
"时间格式:yyyy-MM-dd HH:mm(开始/截止各占两段)\r\n" +
|
"时间格式:yyyy-MM-dd HH:mm(开始/截止各占两段)\r\n" +
|
||||||
"示例:创建比赛 1 NAVI FaZe Quarter-final 2026-03-05 14:00 2026-03-05 13:55\r\n" +
|
"示例:创建比赛 1 NAVI FaZe Quarter-final 2026-03-05 14:00 2026-03-05 13:55\r\n" +
|
||||||
"选项默认 team1_win,team2_win ,可额外添加 score,mvp");
|
"选项默认 team1_win,team2_win ,比分和MVP选项只允许独立添加:score,mvp");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,11 +324,28 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
string options = "team1_win,team2_win";
|
// 解析剩余参数:选项和赔率
|
||||||
if (parts.Length > 8)
|
List<string> optionParts = [];
|
||||||
|
decimal? team1Odds = null, team2Odds = null;
|
||||||
|
for (int i = 8; i < parts.Length; i++)
|
||||||
{
|
{
|
||||||
options = string.Join(",", parts[8..]); // 剩余部分视为选项列表
|
string segment = parts[i];
|
||||||
|
if (segment.StartsWith("team1_win="))
|
||||||
|
{
|
||||||
|
if (decimal.TryParse(segment[11..], out decimal odds1))
|
||||||
|
team1Odds = odds1;
|
||||||
|
}
|
||||||
|
else if (segment.StartsWith("team2_win="))
|
||||||
|
{
|
||||||
|
if (decimal.TryParse(segment[11..], out decimal odds2))
|
||||||
|
team2Odds = odds2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
optionParts.Add(segment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
string options = optionParts.Count > 0 ? string.Join(",", optionParts) : "team1_win,team2_win";
|
||||||
|
|
||||||
BotReply reply = BettingController.CreateMatch(new CreateMatchRequest
|
BotReply reply = BettingController.CreateMatch(new CreateMatchRequest
|
||||||
{
|
{
|
||||||
@ -334,12 +356,44 @@ namespace Oshima.FunGame.WebAPI.Services
|
|||||||
Stage = stage,
|
Stage = stage,
|
||||||
StartTime = startDt,
|
StartTime = startDt,
|
||||||
BetDeadline = deadlineDt,
|
BetDeadline = deadlineDt,
|
||||||
AvailableOptions = options
|
AvailableOptions = options,
|
||||||
|
Team1WinOdds = team1Odds,
|
||||||
|
Team2WinOdds = team2Odds
|
||||||
});
|
});
|
||||||
await SendAsync(e, "创建比赛", reply);
|
await SendAsync(e, "创建比赛", reply);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 指令:关闭投注 <比赛ID>
|
||||||
|
if (e.Detail.StartsWith("关闭投注") || e.Detail.StartsWith("结束竞猜"))
|
||||||
|
{
|
||||||
|
e.UseNotice = false;
|
||||||
|
if (!FunGameConstant.UserIdAndUsername.TryGetValue(uid, out User? user) || (!user.IsAdmin && !user.IsOperator))
|
||||||
|
{
|
||||||
|
await SendAsync(e, "关闭投注", "你没有权限执行此操作。");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
string detail = e.Detail
|
||||||
|
.Replace("关闭投注", "")
|
||||||
|
.Replace("结束竞猜", "")
|
||||||
|
.Trim();
|
||||||
|
if (int.TryParse(detail, out int matchId))
|
||||||
|
{
|
||||||
|
BotReply reply = BettingController.CloseBetting(uid, matchId);
|
||||||
|
reply.Keyboard = new KeyboardMessage()
|
||||||
|
.AppendButtons(2,
|
||||||
|
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
|
||||||
|
Button.CreateCmdButton("🔍 比赛详情", $"比赛详情 {matchId}"));
|
||||||
|
await SendAsync(e, "关闭投注", reply);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await SendAsync(e, "关闭投注", "格式:关闭投注 <比赛ID>");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user