This commit is contained in:
2026-07-09 14:29:17 +08:00
parent 772b700577
commit 79147f6d47
19 changed files with 1635 additions and 30 deletions
@@ -20,6 +20,7 @@ public class GameManager : MonoSingleton<GameManager>
public BotConfig botConfig; // 人机AI详细配置(Inspector可调,本地测试用)
public GameConfig gameConfig;
public ActivityConfig activityConfig;
public Dictionary<string, FishTypeConfig> dic_fishTypeConfigs = new Dictionary<string, FishTypeConfig>();
public UserData user;
public GameData gameData = new GameData();
@@ -222,6 +223,8 @@ public class GameManager : MonoSingleton<GameManager>
}
});
APIRequestList.GetActivityConfig(res => { activityConfig = res; });
}
public async Task InItLoad()
{
+2
View File
@@ -45,6 +45,7 @@ namespace Assets.MyGame.Scripts.Net
dic_API[APIType.ActivityConfig_RegisterConfig] = "/api/ActivityConfig/registerConfig";
dic_API[APIType.ActivityConfig_BattleOrderConfig] = "/api/ActivityConfig/battleOrderConfig";
dic_API[APIType.ActivityConfig_FishingReturnConfig] = "/api/ActivityConfig/fishingReturnConfig";
dic_API[APIType.ActivityConfig_RankingRewardConfig] = "/api/ActivityConfig/rankingRewardConfig";
// ---------------- Hall ----------------
dic_API[APIType.Hall_SaveSafeBox] = "/api/Hall/SaveSafeBox";
@@ -162,6 +163,7 @@ namespace Assets.MyGame.Scripts.Net
dic_API[APIType.Rank_GetUserList] = "/api/User/GetUserList";
dic_API[APIType.Hall_GetRanking] = "/api/Hall/GetRanking";
dic_API[APIType.Hall_GetChessRoomPartitionCount] = "/api/Hall/GetChessRoomPartitionCount";
dic_API[APIType.Hall_SendBroadcast] = "/api/Hall/SendBroadcast";
// ---------------- Customer ----------------
dic_API[APIType.Customer_Start] = "/customerapi/Customer/start";
@@ -194,4 +194,11 @@ namespace Assets.MyGame.Scripts.Net.APIRequest.Params
{
public int taskType = -1; // -1=全部
}
/// <summary>发送全服广播(GET)</summary>
[Serializable]
public class SendBroadcastParam : RequestParamBase
{
public string message;
}
}
@@ -74,6 +74,15 @@ namespace Assets.MyGame.Scripts.Net
APIManager.Response<FishingReturnConfig>(APIType.ActivityConfig_FishingReturnConfig, callback);
}
/// <summary>
/// 获取排行榜奖励配置(GET)
/// 返回:RankingRewardConfig
/// </summary>
public static void GetRankingRewardConfig(Action<RankingRewardConfig> callback)
{
APIManager.Response<RankingRewardConfig>(APIType.ActivityConfig_RankingRewardConfig, callback);
}
#endregion
}
}
@@ -296,6 +296,18 @@ namespace Assets.MyGame.Scripts.Net
APIManager.Response<int>(APIType.Hall_GetChessRoomPartitionCount, callback);
}
/// <summary>
/// 发送全服广播(GET /api/Hall/SendBroadcast?message=xxx)
/// 返回:string
/// </summary>
public static void SendBroadcast(string message, Action<string> callback = null)
{
APIManager.Response<string>(APIType.Hall_SendBroadcast, new SendBroadcastParam
{
message = message
}, callback);
}
#endregion
}
}
@@ -66,5 +66,10 @@ namespace Assets.MyGame.Scripts.Net.API
/// 抽奖活动配置
/// </summary>
public LotteryActivityConfig lotteryActivityConfig;
/// <summary>
/// 排名奖励配置
/// </summary>
public RankingRewardConfig rankingRewardConfig;
}
}
@@ -0,0 +1,51 @@
using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
using System;
using System.Collections.Generic;
namespace Assets.MyGame.Scripts.Net.API
{
/// <summary>
/// 排行榜奖励配置
/// Swagger: /api/ActivityConfig/rankingRewardConfig
/// </summary>
[Serializable]
public class RankingRewardConfig
{
/// <summary>总开关</summary>
public bool isEnabled;
/// <summary>排行榜奖励分组列表</summary>
public List<RankingRewardGroup> groups;
}
/// <summary>
/// 排行榜奖励分组(按排行类型区分:金币榜/等级榜/消耗榜)
/// </summary>
[Serializable]
public class RankingRewardGroup
{
/// <summary>排行榜类型 1=金币 2=等级 3=今日消耗</summary>
public int rankingType;
/// <summary>排行榜名称</summary>
public string name;
/// <summary>排名奖励列表</summary>
public List<RankingRewardItem> rewards;
}
/// <summary>
/// 单个排名奖励
/// </summary>
[Serializable]
public class RankingRewardItem
{
/// <summary>排名起始</summary>
public int rankMin;
/// <summary>排名结束</summary>
public int rankMax;
/// <summary>金币奖励</summary>
public long gold;
/// <summary>钻石奖励</summary>
public int diamond;
/// <summary>道具奖励</summary>
public List<GiftConfig> items;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 74847fe813711e846b11b409958a96ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+6
View File
@@ -43,6 +43,9 @@ namespace Assets.MyGame.Scripts.Net
/// <summary>捕鱼返利配置(GET)</summary>
ActivityConfig_FishingReturnConfig,
/// <summary>排行榜奖励配置(GET)</summary>
ActivityConfig_RankingRewardConfig,
// ---------------- Hall ----------------
/// <summary>存入保险箱(GET)</summary>
@@ -330,6 +333,9 @@ namespace Assets.MyGame.Scripts.Net
/// <summary>获取象棋分区总数(GET)</summary>
Hall_GetChessRoomPartitionCount,
/// <summary>发送全服广播(GET)</summary>
Hall_SendBroadcast,
// ---------------- Customer ----------------
/// <summary>发起会话(POST)</summary>
@@ -103,6 +103,10 @@ namespace Assets.MyGame.Scripts.Net
roomMainPanel.subUIManager.CloseAll();
roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQGameExplain, msg);
break;
// 房主开始游戏 → 通知红方配金币
case "GoldConfigRequired":
roomMainPanel.OnGoldConfigRequired(msg);
break;
//单发给触发人
case "GoldConfigSuccess":
@@ -39,6 +39,11 @@ public partial class WebSocketSendList
// ======== 新增缺失方法 ========
public static void StartGameChineseChess(string gameId, string userId)
{
WebSocketManager.Instance.Send(SocketType.chess, "{\"type\":1,\"target\":\"StartGame\",\"invocationId\":\"1\",\"arguments\":[\"" + gameId + "\",\"" + userId + "\"]}");
}
public static void RestartGameChineseChess(string gameId, string userId)
{
WebSocketManager.Instance.Send(SocketType.chess, "{\"type\":1,\"target\":\"RestartGame\",\"invocationId\":\"1\",\"arguments\":[\"" + gameId + "\",\"" + userId + "\"]}");
@@ -14,6 +14,16 @@ public class HintData
public int hintType; //1求和2认输
}
/// <summary>
/// GoldConfigRequired Socket 推送数据
/// </summary>
[Serializable]
public class GoldConfigRequiredData
{
public string targetUserId;
public ChessGameRoom room;
}
public enum CountdownType
{
WaitPlayer, // 等待玩家进入,超时 → 退出到选房
@@ -103,67 +113,86 @@ public class ChineseChessMainPanel : GameMainPanel_Base
public void StartGame(string msg)
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg.ToString());
ChessGameRoom chessGameRoom = va.arguments[0];
//UpdateUserData(chessGameRoom);
//这里要提前设置房间头像金币信息
UpdateUserData(chessGameRoom);
switch (chessGameRoom.users.Count)
{
case 1:
{
//等待玩家加入
tmp_Name_Top.text = "等待玩家进入";
tmp_CoinCount_Top.text = "";
img_Title_Top.gameObject.SetActive(false);
// 上下都显示等待倒计时
if (tmp_WaitTime_Bottom != null) tmp_WaitTime_Bottom.text = "等待玩家进入02:00";
if (tmp_WaitTime_Top != null) tmp_WaitTime_Top.text = "等待玩家进入02:00";
// 默认2分钟
StartWaitCountdown(120, CountdownType.WaitPlayer, "等待玩家进入");
}
break;
case 2:
{
// 玩家已进入,停止等待进入倒计时
StopWaitCountdown();
img_Title_Top.gameObject.SetActive(true);
// 判断是否为房主(房间第一个用户)
// 判断是否为房主
bool isRoomOwner = chessGameRoom.users.Count > 0
&& chessGameRoom.users[0].userId == GameManager.Instance.user.BaseInfo.number;
if (isRoomOwner)
{
// 房主:显示开始按钮
btn_StartGame.gameObject.SetActive(true);
btn_StartGame.onClick.RemoveAllListeners();
btn_StartGame.onClick.AddListener(() =>
{
// 房主点击开始 → 隐藏开始按钮,弹出金币设置
// 房主点击开始 → 发送 StartGame Socket 请求
btn_StartGame.gameObject.SetActive(false);
StopWaitCountdown();
subUIManager.ShowAsync(UIPanel.ZGXQSelectCoin, chessGameRoom);
StartWaitCountdown(60, CountdownType.WaitSetCoin, "等待设置金额");
WebSocketSendList.StartGameChineseChess(chessGameRoom.roomId, GameManager.Instance.user.BaseInfo.number);
});
}
else
{
// 非房主:隐藏开始按钮
btn_StartGame.gameObject.SetActive(false);
}
// 显示等待房主开始倒计时(60秒)
StartWaitCountdown(60, CountdownType.WaitHostStart, "等待房主开始游戏");
}
break;
default:
break;
}
}
/// <summary>
/// 服务端推送 GoldConfigRequired → 显示金币设置面板(红方配置)
/// data: { targetUserId, room }
/// </summary>
public void OnGoldConfigRequired(string msg)
{
StopWaitCountdown();
var result = JsonConvert.DeserializeObject<WebSocketResponseBase<GoldConfigRequiredData>>(msg);
var data = result.arguments[0];
// 更新房间数据
if (data.room != null)
{
roomData = data.room;
UpdateUserData(data.room);
}
// 判断当前用户是否为红方(targetUserId)
bool isRedSide = data.targetUserId == GameManager.Instance.user.BaseInfo.number;
if (isRedSide)
{
// 红方显示金币设置面板
subUIManager.ShowAsync(UIPanel.ZGXQSelectCoin, roomData);
StartWaitCountdown(60, CountdownType.WaitSetCoin, "等待设置金额");
}
else
{
// 黑方等待红方设置金币
StartWaitCountdown(60, CountdownType.WaitSetCoin, "等待对方设置金额");
}
}
public void UpdateUserData(ChessGameRoom chessGameRoom)
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,5 @@
using Assets.MyGame.Scripts.Net;
using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
using Assets.MyGame.Scripts.Net.API.UserData_SubClass;
using System.Collections.Generic;
using TMPro;
@@ -54,7 +55,7 @@ public class RankLineItem : MonoBehaviour
}
}
public void Init(int rankNum, string name, string level, string score, Sprite sprite, string avatarUrl, string avatarFrameUrl = null, List<BaseProductCount> propItems=null)
public void Init(int rankNum, string name, string level, string score, Sprite sprite, string avatarUrl, string avatarFrameUrl = null, List<GiftConfig> giftItems = null)
{
myAvatarName = avatarUrl;
myAvatarFrameName = avatarFrameUrl;
@@ -96,14 +97,15 @@ public class RankLineItem : MonoBehaviour
avatarFrame.gameObject.SetActive(false);
}
}
if (propItems!=null&&propItems.Count>0)
if (giftItems != null && giftItems.Count > 0)
{
foreach (var product in propItems)
foreach (var gift in giftItems)
{
if (gift?.product == null) continue;
GameObject obj = Instantiate(backPackPropItemPrefab.gameObject, backPackPropItemRarent);
var tempItem = obj.GetComponent<BackPackPropItem>();
tempItem.Init(APIManager.baseURL + product.imageUrl, product.count, (PropEnum)product.type);
int count = gift.isRandom ? gift.minCount : gift.count;
tempItem.Init(APIManager.baseURL + gift.product.imageUrl, count, (PropEnum)gift.product.type);
}
}
}
@@ -32,6 +32,12 @@ public class UIHome_BY_BackPackPanel : SubUIBase
public GameObject changNamePanel;
public TMP_InputField tMPText_NewName;
public Button btn_ChangeName;
[Header("大喇叭")]//使用大喇叭后,弹出输入框,输入弹幕,点击确定按钮,发送请求
public GameObject DaLaBaPanel;
public TMP_InputField tMPText_DaLaBaLabel;
public Button btn_FaSong;
// 刷新时保存的状态
//private Vector2 savedScrollPos;
private string savedPropID;
@@ -48,6 +54,29 @@ public class UIHome_BY_BackPackPanel : SubUIBase
// 改名面板默认关闭
if (changNamePanel != null)
changNamePanel.SetActive(false);
// 大喇叭
if (DaLaBaPanel != null)
DaLaBaPanel.SetActive(false);
if (btn_FaSong != null)
btn_FaSong.onClick.AddListener(OnClickFaSong);
}
private void OnClickFaSong()
{
string msg = "广播:"+ tMPText_DaLaBaLabel?.text?.Trim();
if (string.IsNullOrEmpty(msg))
{
UIManager.Instance.ShowBoardError("请输入广播内容");
return;
}
APIRequestList.SendBroadcast(msg, (result) =>
{
//UIManager.Instance.ShowBoardGongGao($"广播: {msg}");
tMPText_DaLaBaLabel.text = "";
DaLaBaPanel.SetActive(false);
});
}
private void OnClickConfirmChangeName()
@@ -172,7 +201,10 @@ public class UIHome_BY_BackPackPanel : SubUIBase
if (changNamePanel != null)
changNamePanel.SetActive(true);
break;
case PropEnum.大喇叭: break;
case PropEnum.大喇叭:
if (DaLaBaPanel != null)
DaLaBaPanel.SetActive(true);
break;
case PropEnum.技能: break;
case PropEnum.召唤卡: break;
default: break;
@@ -1,5 +1,8 @@
using Assets.Framework.Tool;
using Assets.MyGame.Scripts.Net;
using Assets.MyGame.Scripts.Net.API;
using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
using Assets.MyGame.Scripts.Net.API.UserData_SubClass;
using Assets.MyGame.Scripts.Net.APIRequest.Params;
using Assets.MyGame.Scripts.Net.APIResponses;
using System.Collections.Generic;
@@ -29,11 +32,22 @@ public class UIHome_BY_RankPanel : SubUIBase
private int _currentRankType = 1;
private static readonly string[] RankTypeNames = { "", "金币排行", "等级排行", "今日消耗排行" };
private RankingRewardConfig _rankingRewardConfig;
protected override void OnShow(object args = null)
{
base.OnShow(args);
// 加载排名奖励配置
if (_rankingRewardConfig == null)
{
APIRequestList.GetRankingRewardConfig(cfg =>
{
_rankingRewardConfig = cfg;
SwitchRankType(_currentRankType);
});
}
// ---- Toggle 监听 ----
if (toggle_GlodRank != null)
toggle_GlodRank.onValueChanged.AddListener((isOn) => { if (isOn) SwitchRankType(1); });
@@ -87,15 +101,16 @@ public class UIHome_BY_RankPanel : SubUIBase
var item = Instantiate(obj_LinePrefab, prefabRankLineItem_parent);
var sprite = GameManager.Instance.GetAvatarSprite(data.avatarUrl);
var rewards = GetRankRewards(data.rank);
// Init(rankNum, name, level, score, sprite, avatarUrl)
item.Init(
data.rank, // 排名
data.nickName ?? data.userName ?? "—", // 昵称
data.level > 0 ? $"Lv.{data.level}" : "—", // 等级
FormatRankingValue(data.rankingValue), // 排行数值
data.rank,
data.nickName ?? data.userName ?? "—",
data.level > 0 ? $"Lv.{data.level}" : "—",
FormatRankingValue(data.rankingValue),
sprite,
data.avatarUrl
data.avatarUrl,
giftItems: rewards
);
}
}
@@ -107,6 +122,7 @@ public class UIHome_BY_RankPanel : SubUIBase
{
var me = response.user;
var sprite = GameManager.Instance.GetAvatarSprite(me.avatarUrl);
var myRewards = GetRankRewards(me.rank);
myobj_Line.gameObject.SetActive(true);
myobj_Line.Init(
@@ -116,7 +132,8 @@ public class UIHome_BY_RankPanel : SubUIBase
FormatRankingValue(me.rankingValue),
sprite,
me.avatarUrl,
GameManager.Instance.user.BaseInfo.avatarFrame
GameManager.Instance.user.BaseInfo.avatarFrame,
myRewards
);
}
else
@@ -154,6 +171,16 @@ public class UIHome_BY_RankPanel : SubUIBase
return gold.ToString("N0");
}
/// <summary>根据排行类型和排名查找奖励道具</summary>
private List<GiftConfig> GetRankRewards(int rank)
{
if (_rankingRewardConfig == null || !_rankingRewardConfig.isEnabled) return null;
var group = _rankingRewardConfig.groups?.Find(g => g.rankingType == _currentRankType);
if (group?.rewards == null) return null;
var match = group.rewards.Find(r => rank >= r.rankMin && rank <= r.rankMax);
return match?.items;
}
private void ClearRankList()
{
if (prefabRankLineItem_parent == null) return;
+29 -1
View File
@@ -459,6 +459,34 @@ public class ZhanLing_Panel : SubUIBase
return (list != null && list.Count > 0) ? list[0] : null;
}
/// <summary>HTML 转 TextMeshPro 兼容格式</summary>
private static string HtmlToTMP(string html)
{
if (string.IsNullOrEmpty(html)) return html;
string result = html;
// <br/> / <br /> → <br>
result = System.Text.RegularExpressions.Regex.Replace(result, @"<br\s*/?>", "<br>");
// <p> </p> → 去标签,末尾加换行
result = System.Text.RegularExpressions.Regex.Replace(result, @"</p>", "\n");
result = System.Text.RegularExpressions.Regex.Replace(result, @"<p[^>]*>", "");
// \n 转义
result = result.Replace("\\n", "\n");
// <div> </div>
result = System.Text.RegularExpressions.Regex.Replace(result, @"</div>", "\n");
result = System.Text.RegularExpressions.Regex.Replace(result, @"<div[^>]*>", "");
// <font ...> </font> → 去掉标签保留内容(TMP 不支持动态切换字体)
result = System.Text.RegularExpressions.Regex.Replace(result, @"</font>", "");
result = System.Text.RegularExpressions.Regex.Replace(result, @"<font[^>]*>", "");
// <span> </span> → 去标签保留内容
result = System.Text.RegularExpressions.Regex.Replace(result, @"</?span[^>]*>", "");
// &nbsp;
result = result.Replace("&nbsp;", " ");
// 多余空行
result = System.Text.RegularExpressions.Regex.Replace(result, @"\n{3,}", "\n\n");
return result;
}
/// <summary>刷新战令剩余时间(格式:30天10:01:50)</summary>
private void RefreshActiveTime()
{
@@ -536,7 +564,7 @@ public class ZhanLing_Panel : SubUIBase
{
if (notice == null) return;
if (tmp_TitleLabel != null) tmp_TitleLabel.text = notice.title;
if (tmp_Content != null) tmp_Content.text = notice.content;
if (tmp_Content != null) tmp_Content.text = HtmlToTMP(notice.content);
// 加载顶部图片
if (img_TopImg != null && !string.IsNullOrEmpty(notice.topImage))
Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 17 KiB