Refactors, Introduce GameManager, Lobby work, Docs
This commit is contained in:
@@ -49,21 +49,40 @@
|
||||
"Components": [
|
||||
{
|
||||
"__type": "LuckerParty.NetworkManager",
|
||||
"__guid": "66cfc3ad-f9a2-49fa-b72b-cf0498aadfad",
|
||||
"ClientGroup": {
|
||||
"_type": "gameobject",
|
||||
"go": "3a8c9a1d-2623-4041-bb55-40bce397cd02"
|
||||
}
|
||||
}
|
||||
]
|
||||
"__guid": "beaf09d7-3c2d-4ce3-9607-24ee3b4e5617"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"__guid": "3a8c9a1d-2623-4041-bb55-40bce397cd02",
|
||||
"__guid": "c1903bc9-6a9f-41b5-bed7-b4fb2d50fcde",
|
||||
"Flags": 0,
|
||||
"Name": "Clients",
|
||||
"Enabled": true
|
||||
"Name": "Game Manager",
|
||||
"Enabled": true,
|
||||
"Components": [
|
||||
{
|
||||
"__type": "LuckerParty.GameManager",
|
||||
"__guid": "053898a9-71a7-48a7-9ebc-3c57d6ec5ca4"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"__guid": "076002c4-f60b-4ccc-8306-416e80d700df",
|
||||
"Flags": 0,
|
||||
"Name": "UI Root",
|
||||
"Enabled": true,
|
||||
"Components": [
|
||||
{
|
||||
"__type": "Sandbox.ScreenPanel",
|
||||
"__guid": "f6380618-4c54-4bdc-9dee-ab8705b685cf",
|
||||
"AutoScreenScale": true,
|
||||
"Opacity": 1,
|
||||
"Scale": 1,
|
||||
"ScaleStrategy": "ConsistentHeight",
|
||||
"ZIndex": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"__guid": "97cb86cc-36d4-46cf-8506-c1bc373ed142",
|
||||
|
||||
48
Docs/game-design.md
Normal file
48
Docs/game-design.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Game Design
|
||||
|
||||
This document details how Lucker Party is intended to work by describing how the game flows from start to finish.
|
||||
|
||||
But right now it's just a brainstorming document for the technical architecture.
|
||||
|
||||
## Terms
|
||||
|
||||
- **Lobby** - The initial game state where players get ready to play a Round.
|
||||
- **Round** - A number of minigames played back-to-back. A Round starts when the Host starts the game from the Lobby.
|
||||
- **Minigame** - An individual custom game that all players score points in.
|
||||
- **Player** - an active member of the round. Players can get points and will be included in the Round stats
|
||||
- **Spectator** - A Client that's not an active member of the round. The minigame can choose what controls the Spectator
|
||||
receives to interact with the scene.
|
||||
|
||||
## Lobby
|
||||
|
||||
### Creation
|
||||
|
||||
When the lobby is initially created by the host, a Lobby UI is presented to the host and anyone else who joins
|
||||
thereafter.
|
||||
|
||||
### Lobby UI
|
||||
|
||||
The Lobby UI shows:
|
||||
|
||||
- The list of Clients
|
||||
- Game Settings
|
||||
- Number of minigames
|
||||
- Client Settings
|
||||
- Color - This player's visual tint for identification in the mini games
|
||||
- A Start Game button
|
||||
|
||||
When the Start Game button is pressed a countdown starts, and after the first minigame starts
|
||||
|
||||
## Round Manager
|
||||
|
||||
Manages the current Round. Starting, stopping, triggering minigames from the manager, etc.
|
||||
|
||||
Think of the Round Manager as the orchestrator of the set of minigames for the round.
|
||||
|
||||
The round manager has different states that is passes through from start to finish of a Round. Some ideas that aren't
|
||||
implemented yet:
|
||||
|
||||
- Countdown before the first minigame
|
||||
- Starting a minigame
|
||||
- Pausing a minigame
|
||||
- Receives signal from the Minigame that it has finished
|
||||
@@ -1,4 +1,4 @@
|
||||
using LuckerParty.UI;
|
||||
using System;
|
||||
|
||||
namespace LuckerParty;
|
||||
|
||||
@@ -10,9 +10,10 @@ public sealed class Client : Component
|
||||
{
|
||||
public Connection Connection { get; set; }
|
||||
|
||||
public string Name => Connection.DisplayName;
|
||||
public DateTimeOffset ConnectionTime => Connection.ConnectionTime;
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
GameObject.AddComponent<ScreenPanel>();
|
||||
GameObject.AddComponent<Hud>();
|
||||
}
|
||||
}
|
||||
|
||||
22
code/GameManager.cs
Normal file
22
code/GameManager.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace LuckerParty;
|
||||
|
||||
/// <summary>
|
||||
/// Manages the Game state, which right now is either Lobby or Round.
|
||||
/// Maintains the lifecycle of the Lobby and Round Managers.
|
||||
/// </summary>
|
||||
public sealed class GameManager : Component
|
||||
{
|
||||
public enum State
|
||||
{
|
||||
Lobby,
|
||||
Round
|
||||
}
|
||||
|
||||
public State CurrentState { get; private set; } = State.Lobby;
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
// Start Lobby
|
||||
GameObject.AddComponent<LobbyManager>();
|
||||
}
|
||||
}
|
||||
25
code/LobbyManager.cs
Normal file
25
code/LobbyManager.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using LuckerParty.UI;
|
||||
|
||||
namespace LuckerParty;
|
||||
|
||||
public sealed class LobbyManager : Component
|
||||
{
|
||||
private PanelComponent _panelComponent;
|
||||
|
||||
protected override void OnEnabled()
|
||||
{
|
||||
var screenPanel = Scene.Directory.FindByName( "UI Root" ).First();
|
||||
_panelComponent = screenPanel.AddComponent<Lobby>();
|
||||
}
|
||||
|
||||
protected override void OnDisabled()
|
||||
{
|
||||
_panelComponent.Destroy();
|
||||
_panelComponent = null;
|
||||
}
|
||||
|
||||
public interface ILobbyEvent : ISceneEvent<ILobbyEvent>
|
||||
{
|
||||
void OnStartGame( RoundConfiguration roundConfiguration );
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,12 @@ public sealed class NetworkManager : Component, Component.INetworkListener
|
||||
/// <summary>
|
||||
/// A GameObject used for organizational grouping of Clients
|
||||
/// </summary>
|
||||
private GameObject ClientGroup { get; set; }
|
||||
private GameObject _clientGroup;
|
||||
|
||||
public void OnActive( Connection channel )
|
||||
{
|
||||
// Set up the Client GameObject
|
||||
var gameObject = new GameObject( ClientGroup ) { Name = $"{channel.DisplayName} ({channel.SteamId})" };
|
||||
var gameObject = new GameObject( _clientGroup ) { Name = $"{channel.DisplayName} ({channel.SteamId})" };
|
||||
_clientMap.Add( channel, gameObject );
|
||||
var client = gameObject.AddComponent<Client>();
|
||||
client.Connection = channel;
|
||||
@@ -41,11 +41,11 @@ public sealed class NetworkManager : Component, Component.INetworkListener
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
ClientGroup = new GameObject( Scene.Root );
|
||||
_clientGroup = new GameObject( Scene.Root ) { Name = "Clients", NetworkMode = NetworkMode.Object };
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
ClientGroup.Destroy();
|
||||
_clientGroup.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
9
code/RoundConfiguration.cs
Normal file
9
code/RoundConfiguration.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace LuckerParty;
|
||||
|
||||
/// <summary>
|
||||
/// Contains configuration for a Round, usually created by the host in a Lobby.
|
||||
/// </summary>
|
||||
public class RoundConfiguration
|
||||
{
|
||||
public uint NumberOfMinigames { get; set; }
|
||||
}
|
||||
@@ -1,27 +1,20 @@
|
||||
@namespace LuckerParty.UI
|
||||
@using System
|
||||
@inherits PanelComponent
|
||||
@namespace LuckerParty.UI
|
||||
|
||||
<root>
|
||||
<div class="title">Hello, @_name</div>
|
||||
<div class="title">This is the Lobby</div>
|
||||
</root>
|
||||
|
||||
@code
|
||||
{
|
||||
|
||||
private string _name;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
base.OnAwake();
|
||||
_name = GameObject.GetComponent<Client>().Connection.DisplayName;
|
||||
}
|
||||
public List<Client> Clients { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// the hash determines if the system should be rebuilt. If it changes, it will be rebuilt
|
||||
/// </summary>
|
||||
protected override int BuildHash()
|
||||
{
|
||||
return HashCode.Combine( _name );
|
||||
return HashCode.Combine( Clients );
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Title": "Lucker Party",
|
||||
"Type": "game",
|
||||
"Org": "local",
|
||||
"Org": "concoshut",
|
||||
"Ident": "lucker_party",
|
||||
"Schema": 1,
|
||||
"IncludeSourceFiles": false,
|
||||
@@ -22,6 +22,22 @@
|
||||
"PerMapRanking": false,
|
||||
"LeaderboardType": "None",
|
||||
"CsProjName": "",
|
||||
"StartupScene": "scenes/minimal.scene"
|
||||
"StartupScene": "scenes/minimal.scene",
|
||||
"Compiler": {
|
||||
"RootNamespace": "LuckerParty",
|
||||
"DefineConstants": "SANDBOX;ADDON;DEBUG",
|
||||
"NoWarn": "1701;1702;1591;",
|
||||
"WarningsAsErrors": "",
|
||||
"TreatWarningsAsErrors": false,
|
||||
"Nullables": false,
|
||||
"Whitelist": true,
|
||||
"ReleaseMode": "Debug",
|
||||
"AssemblyReferences": [],
|
||||
"IgnoreFolders": [
|
||||
"editor",
|
||||
"unittest"
|
||||
],
|
||||
"DistinctAssemblyReferences": []
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,22 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AComponent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6553e8794aae3c475eef751add553eb427babf32c98ad3ab1988efd1485c_003FComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConnection_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F02714d79d02643c6a10a82f861205a18263400_003Fde_003Fd5c8baea_003FConnection_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConnection_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F19abf87070324a24a498e06d51eb783a263600_003F8b_003Fa645f6c8_003FConnection_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConnection_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4b00eb25dc4a4faab4a2bdf678a7e77c263400_003Ff4_003F6681afe0_003FConnection_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Faa27c7b340a656c1115d184d1479be2351258530dbcfba1a3ffeff49f3345446_003FGameObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameObjectSystem_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F76b045f8cca7c6eeaa4299eff84149b33e2523235887981e9d901d8c4355d_003FGameObjectSystem_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGame_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F262292e54674e2ebba95aeee93cb92cef46fb49c92f9c6f8cf9773747f3f9cc1_003FGame_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AINetworkListener_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fbdd02fd1a914f886538cdccaadc6c813d1b5badfd9fa44d714323b7978b49fe_003FINetworkListener_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInterop_002EEngine_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6efc782a71943dcfe1724f2ab146a2cda4ce446a274ef98adb11282191_003FInterop_002EEngine_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIRootPanelComponent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd597463440aa64db88ab1120e3352a3274112098fef51ce93761058f53f68_003FIRootPanelComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AModelRenderer_002EAttachments_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fb26ca1467e599f1ba7f72867e56dd242371c9e01e56f4d81dedcf73618d973a_003FModelRenderer_002EAttachments_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AModelRenderer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd9493723581e2c8a31b40577dacf1686f31933848f3532d945b83a8527f799_003FModelRenderer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANetworking_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F19abf87070324a24a498e06d51eb783a263600_003Ff3_003F9c09fbee_003FNetworking_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APanelComponent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fdfe3022753e9e5aaa3b2d15b5c5d6e3c43b814e0ba32841351d1e1b89c661_003FPanelComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APlayerController_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F3f23c368a4d12fb02b7ab5e07a8cc801bbd19279b7215bc49c3bd3528f2b4e4_003FPlayerController_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneModel_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F19abf87070324a24a498e06d51eb783a263600_003F73_003F68917622_003FSceneModel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4b00eb25dc4a4faab4a2bdf678a7e77c263400_003Fdf_003Ffb83ae92_003FSceneObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AScreenPanel_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F7f5dea8cfde9dabf40f4c55f473c8604a3ec722c29ebaa2d466ab10cbd58a98_003FScreenPanel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASkinnedModelRenderer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F401fb1a56c933b39db4639ec2a82ab1b14c40fea138d04f429c8440a2e7e7_003FSkinnedModelRenderer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATCPClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F212760d42b6ac7f5778e2cb7bd6eec0eb5edc15575b9775855c7a77f8363_003FTCPClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue"><AssemblyExplorer>
|
||||
|
||||
Reference in New Issue
Block a user