struct VCCUserListToggle { string Name; bool InitFlag; } struct VCCTableUILayout { int X; // Offset X int Y; // Offset Y int MpX; // Mask Pos X int MpY; // Mask Pos Y int MW; // Mask Width int MH; // Mask Height string Ancor; list ToggleList; public VCCTableUILayout() { X = 0; Y = 0; MpX = 0; MpY = 0; MW = 0; MH = 0; Ancor = "LT"; ToggleList = new list(); } public void Init(int _X, int _Y, int _MpX, int _MpY, int _MW, int _MH, string _Ancor) { X = _X; Y = _Y; MpX = _MpX; MpY = _MpY; MW = _MW; MH = _MH; Ancor = _Ancor; } } class VCCJoinUserTable { public int MaxUserCount; // ユーザーテーブル内ユーザー数(Pos, Voice, Liveを気にせずに使いまわせるようにする) public string BaseLayerName; public string IconOnlyLayerName; public string UserListLayerName; public VCCTableUILayout Layout_la; public VCCTableUILayout Layout_po; public VCCTableUILayout Layout_xr; public list Data; public list StashData; // 一時非表示中のユーザーリスト public string CreateUserCode; public list DelayUserProfileList; // 遅延ユーザープロフィール追加リスト(UserProfileカスタムステートが空だったので後で追加するリスト) public VCCJoinUserTable() { MaxUserCount = 0; Data = new list(); StashData = new list(); DelayUserProfileList = new list(); } public int Count() { return Data.Count; } public void Init(string _BaseLayerName, string _IconOnlyLayerName, string _UserListLayerName, VCCTableUILayout la, VCCTableUILayout po, VCCTableUILayout xr) { BaseLayerName = _BaseLayerName; IconOnlyLayerName = _IconOnlyLayerName; UserListLayerName = _UserListLayerName; Layout_la = la; Layout_po = po; Layout_xr = xr; _LoadIconOnlyUserListLayer(false); _LoadIconOnlyUserListLayer(true); _LoadNameUserList("la"); _LoadNameUserList("po"); _LoadNameUserList("xr"); } public void Release() { // ユーザーリストとそのUIを削除 Clear(); // レイヤーを削除 if(!IconOnlyLayerName.IsEmpty()) system.Canvas_ReleaseLayer(IconOnlyLayerName, false); if(!IconOnlyLayerName.IsEmpty()) system.Canvas_ReleaseLayer(IconOnlyLayerName, true); if(!UserListLayerName.IsEmpty()) system.Canvas_ReleaseLayer(UserListLayerName, false); if(!UserListLayerName.IsEmpty()) system.Canvas_ReleaseLayer(UserListLayerName, true); } bool _ChackIsChannelCreator(string checkUserCode) { if(CreateUserCode.IsEmpty() || checkUserCode.IsEmpty()) return false; return (checkUserCode == CreateUserCode); } public void Clear() { // for(int i = 0; i < Data.Count; i++) { VCCUserData elm = Data[i]; elm.Release(); } Data.Clear(); // for(int i = 0; i < StashData.Count; i++) { VCCUserData elm = StashData[i]; elm.Release(); } StashData.Clear(); CreateUserCode = ""; MaxUserCount = 0; } public void Add(VCCUserData user) { // 同一PlayerIDまたは同一UserCodeのユーザーが存在したら追加しない for(int i = 0; i < Data.Count; i++) { if(Data[i].PlayerID == user.PlayerID || Data[i].UserCode == user.UserCode) return; } user.TableOrder = Data.Count; user.IsChannelCreator = _ChackIsChannelCreator(user.UserCode); // GUIをロードする user.Load(Data, IconOnlyLayerName, UserListLayerName, Layout_la, Layout_po, Layout_xr); Data.Add(user); _UpdateCurrentPlayerCount(); } public void AddFromUserProfile(string ID, string UserProfile) { JsVal val = makeJsValFromJson(UserProfile); string user_code = val.GetProperty("user_code").GetStr(); string user_type = val.GetProperty("user_type").GetStr(); string user_name = val.GetProperty("user_name").GetStr(); string icon_url = val.GetProperty("icon_url").GetStr(); VCCUserData User = new VCCUserData(); User.PlayerID = ID; User.UserCode = user_code; User.UserType = user_type; User.UserName = user_name; User.IconURL = icon_url; Add(User); } public void RemoveAt(int index) { // GUIとリストの要素をリリースする Data[index].Release(); Data.RemoveAt(index); // テーブルでのOrderとPosを更新する _UpdateCurrentPlayerCount(); for(int i = 0; i < Data.Count; i++) { if(Data[i].TableOrder < index) continue; Data[i].TableOrder = i; Data[i].UpdateGUIPos(i, Data, Layout_la, Layout_po, Layout_xr); } } void _UpdateCurrentPlayerCount() { JsVal val = makeJsObj(); val.AddPropertyByVal("layername", makeJsStrFrom(BaseLayerName)); val.AddPropertyByVal("joinusercount", makeJsNumFrom(Data.Count)); val.AddPropertyByVal("maxusercount", makeJsNumFrom(MaxUserCount)); LayerBundle layer = hsLayerGet("vcc_icon_only_base"); if(layer !== null) layer.CallComponentMethod("VCCViewModel", "UpdateCurrentPlayerCount", val.ToString()); } public void UpdateUserData(int UserIndex, string channel_session_code, string user_code, string user_type, string user_name, string icon_url) { if(UserIndex == -1 || UserIndex >= Data.Count) return; Data[UserIndex].ChannelSessionCode = channel_session_code; Data[UserIndex].UserCode = user_code; Data[UserIndex].UserType = user_type; Data[UserIndex].UserName = user_name; Data[UserIndex].IconURL = icon_url; Data[UserIndex].IsChannelCreator = _ChackIsChannelCreator(user_code); Data[UserIndex].UpdateGUIResource(); } public void UpdateSelfUserData(VCCUserData SelfUser) { SelfUser.IsChannelCreator = _ChackIsChannelCreator(SelfUser.UserCode); SelfUser.UpdateGUIResource(); } public void PushUserDataStash(string PlayerID) { for(int i = 0; i < Data.Count; i++) { if(!PlayerID.IsEmpty() && Data[i].PlayerID == PlayerID) { // 指定されたユーザーをStashDataに入れる StashData.Add(Data[i]); // Dataからはいったん削除する RemoveAt(i); break; } } } public void ApplyUserDataStash(string PlayerID) { for(int i = 0; i < StashData.Count; i++) { if(!PlayerID.IsEmpty() && StashData[i].PlayerID == PlayerID) { // Dataの末尾に再び追加する Add(StashData[i]); // StashDataから取り除く StashData.RemoveAt(i); break; } } } public void DropUserDataStash(string PlayerID) { for(int i = 0; i < StashData.Count; i++) { if(!PlayerID.IsEmpty() && StashData[i].PlayerID == PlayerID) { // StashDataから取り除く StashData.RemoveAt(i); break; } } } public bool IsExistUserCode(string UserCode) { // テーブル内にユーザーが存在するかどうか for(int i = 0; i < Data.Count; i++) { if(Data[i].UserCode == UserCode) { return true; } } return false; } public bool IsExistDelayUserProfile(string PlayerID) { for(int i = 0; i < DelayUserProfileList.Count; i++) { if(DelayUserProfileList[i] == PlayerID) { DelayUserProfileList.RemoveAt(i); return true; } } return false; } void _LoadIconOnlyUserListLayer(bool IsPortrait) { // Layerの生成 system.Canvas_AddLayer(IconOnlyLayerName, IsPortrait, true, 12); if(IsPortrait) { system.Canvas_SetLayerMask(IconOnlyLayerName, IsPortrait, "gui2024/clear.png", 367, 453, 480, 309, 0.5, 0.5, "LT", 1, 0.0, 0.0, 0.0, 0.0, false, true, false, 80); } else { system.Canvas_SetLayerMask(IconOnlyLayerName, IsPortrait, "gui2024/clear.png", 119, 154, 173, 120, 0.5, 0.5, "LT", 1, 0.0, 0.0, 0.0, 0.0, false, true, false, 50); } system.Canvas_SetLayerComponentNameList(IconOnlyLayerName, IsPortrait, "VCCController"); hsCanvasSetLayerShow(IconOnlyLayerName, false); } void _LoadNameUserList(string Layout) { bool IsPortrait = false; if(Layout == "po") IsPortrait = true; // WebXRモード用の別レイヤーを生成 string LayerName = UserListLayerName; if(Layout == "xr") LayerName = UserListLayerName + "_webxr"; // Layerの生成 system.Canvas_AddLayer(LayerName, IsPortrait, true, 12); if(Layout == "po") { system.Canvas_SetLayerMask(LayerName, IsPortrait, "gui2024/clear.png", Layout_po.MpX, Layout_po.MpY, Layout_po.MW, Layout_po.MH, 0.5, 0.5, "LT", 1, 0.0, 0.0, 0.0, 0.0, false, true, false, 80); } else if(Layout == "la") { system.Canvas_SetLayerMask(LayerName, IsPortrait, "gui2024/clear.png", Layout_la.MpX, Layout_la.MpY, Layout_la.MW, Layout_la.MH, 0.5, 0.5, "LT", 1, 0.0, 0.0, 0.0, 0.0, false, true, false,50); } else if(Layout == "xr") { system.Canvas_SetLayerMask(LayerName, IsPortrait, "gui2024/clear.png", Layout_xr.MpX, Layout_xr.MpY, Layout_xr.MW, Layout_xr.MH, 0.5, 0.5, "CM", 1, 0.0, 0.0, 0.0, 0.0, false, true, false,50); } system.Canvas_SetLayerComponentNameList(LayerName, IsPortrait, "VCCController"); hsCanvasSetLayerShow(LayerName, false); } }