├── .gitattributes ├── .gitignore ├── ClientCore ├── CCIniFile.cs ├── ClientConfiguration.cs ├── ClientCore.csproj ├── CnCNet5 │ ├── CnCNetGame.cs │ ├── GameCollection.cs │ └── NameValidator.cs ├── Entity │ ├── Badge.cs │ ├── BadgeVo.cs │ ├── Component.cs │ ├── ComponentVo.cs │ ├── InfoBaseClass.cs │ ├── Maps.cs │ ├── Mission.cs │ ├── MissionPack.cs │ ├── Mod.cs │ ├── Music.cs │ ├── Page.cs │ ├── PassDto.cs │ ├── QuestionBank.cs │ ├── Score.cs │ ├── Thank.cs │ ├── Updater.cs │ ├── UpdaterServer.cs │ ├── User.cs │ └── badgeDto.cs ├── Enums │ ├── AllowPrivateMessagesFromEnum.cs │ ├── ResResult.cs │ └── SortDirection.cs ├── Extensions │ ├── EnumExtensions.cs │ ├── EnumerableExtensions.cs │ └── StringExtensions.cs ├── FileFormats │ ├── Blowfish.cs │ ├── BlowfishKeyProvider.cs │ ├── CRC32.cs │ ├── CSF.cs │ ├── Cache.cs │ ├── FileSystem.cs │ ├── Format5.cs │ ├── Format80.cs │ ├── IPackage.cs │ ├── IsoTile.cs │ ├── MemoryFile.cs │ ├── MiniLZO.cs │ ├── MixFile.cs │ ├── PackageEntry.cs │ ├── SegmentStream.cs │ ├── StreamExts.cs │ ├── TileLayer.cs │ ├── TwoDimensionalEnumerator.cs │ ├── VirtualFile.cs │ ├── XccGlobalDatabase.cs │ └── XccLocalDatabase.cs ├── FileHelper.cs ├── FileLockedException.cs ├── INIProcessing │ ├── IniPreprocessInfoStore.cs │ ├── IniPreprocessor.cs │ └── PreprocessorBackgroundTask.cs ├── LoadingScreenController.cs ├── OSVersion.cs ├── PlatformShim │ └── EncodingExt.cs ├── ProcessLauncher.cs ├── ProfanityFilter.cs ├── ProgramConstants.cs ├── RenderImage.cs ├── Resources │ ├── cncneticon.png │ ├── cncricon.png │ ├── d2kicon.png │ ├── dtaicon.png │ ├── moicon.png │ ├── raicon.png │ ├── reicon.png │ ├── rricon.png │ ├── ssicon.png │ ├── tdicon.png │ ├── tiicon.png │ ├── tsicon.png │ ├── unknownicon.png │ └── yricon.png ├── SavedGameManager.cs ├── Settings │ ├── BoolSetting.cs │ ├── DoubleSetting.cs │ ├── IIniSetting.cs │ ├── INISetting.cs │ ├── IntRangeSetting.cs │ ├── IntSetting.cs │ ├── NetWorkINISettings.cs │ ├── StringListSetting.cs │ ├── StringSetting.cs │ ├── Updater.cs │ └── UserINISettings.cs ├── Statistics │ ├── DataWriter.cs │ ├── GameParsers │ │ └── LogFileStatisticsParser.cs │ ├── GenericMatchParser.cs │ ├── GenericStatisticsManager.cs │ ├── MatchStatistics.cs │ ├── PlayerStatistics.cs │ └── StatisticsManager.cs ├── TaskbarProgress.cs └── WebHelper.cs ├── ClientGUI ├── CDebugView.cs ├── ClientGUI.csproj ├── ClientGUICreator.cs ├── DarkeningPanel.cs ├── GameProcessLogic.cs ├── HotKey.cs ├── IME │ ├── DummyIMEHandler.cs │ ├── IMEHandler.cs │ ├── SdlIMEHandler.cs │ └── WinFormsIMEHandler.cs ├── INIConfigException.cs ├── INItializableWindow.cs ├── INItializableXNAWindow.cs ├── Parser.cs ├── ToolTip.cs ├── UIDesignConstants.cs ├── WindowControl.cs ├── XNAChatTextBox.cs ├── XNAClientButton.cs ├── XNAClientCheckBox.cs ├── XNAClientDropDown.cs ├── XNAClientPreferredItemDropDown.cs ├── XNAClientRatingBox.cs ├── XNAClientStateButton.cs ├── XNAClientTabControl.cs ├── XNAClientToggleButton.cs ├── XNAExtraPanel.cs ├── XNALinkButton.cs ├── XNAMessage.cs ├── XNAMessageBox.cs ├── XNAPlayerSlotIndicator.cs ├── XNAWindow.cs ├── XNAWindowBase.cs ├── XNAWindowSingleton.cs └── YRPathWindow.cs ├── ClientUpdater ├── ClientUpdater.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── SafePath.cs └── app.manifest ├── DTAConfig ├── DTAConfig.csproj ├── DTAConfig.csproj.DotSettings ├── DirectDrawWrapper.cs ├── HotkeyConfigurationWindow.cs ├── MusicWindow.cs ├── OptionPanels │ ├── AudioOptionsPanel.cs │ ├── CnCNetOptionsPanel.cs │ ├── ComponentsPanel.cs │ ├── DisplayOptionsPanel.cs │ ├── GameOptionsPanel.cs │ ├── LocalSkinPanel.cs │ ├── MinesweeperGame.cs │ ├── ModManager.cs │ ├── QuestionBankBox.cs │ ├── UpdaterOptionsPanel.cs │ ├── UploadWindow.cs │ ├── UserOptionsPanel.cs │ ├── XNAOptionsPanel.cs │ └── 地图库.cs ├── OptionsWindow.cs ├── Settings │ ├── ColorSpace.cs │ ├── FileSettingCheckBox.cs │ ├── FileSettingDropDown.cs │ ├── FileSourceDestinationInfo.cs │ ├── GameObject.cs │ ├── IFileSetting.cs │ ├── IUserSetting.cs │ ├── Rulesmd.cs │ ├── SettingCheckBox.cs │ ├── SettingCheckBoxBase.cs │ ├── SettingDropDown.cs │ └── SettingDropDownBase.cs └── ThankWindow.cs ├── Docs └── INISystem.md ├── LICENSE ├── Localization ├── ExtensionMethods.cs ├── Localization.csproj ├── MissingTranslationEventArgs.cs ├── SevenZip │ ├── ArchiveFile.cs │ ├── ArchiveFileCallback.cs │ ├── ArchiveStreamCallback.cs │ ├── ArchiveStreamsCallback.cs │ ├── Entry.cs │ ├── Formats.cs │ ├── IArchiveExtractCallback.cs │ ├── Kernel32Dll.cs │ ├── SafeLibraryHandle.cs │ ├── SevenZipException.cs │ ├── SevenZipFormat.cs │ ├── SevenZipHandle.cs │ └── SevenZipInterface.cs ├── Tools │ ├── CryptoUtil.cs │ ├── Mix.cs │ └── ZIP.cs └── TranslationTable.cs ├── RA2Client ├── DXGUI │ ├── GameClass.cs │ ├── Generic │ │ ├── CampaignSelector.cs │ │ ├── CheaterWindow.cs │ │ ├── ComputerUniqueHelper.cs │ │ ├── ExtrasWindow.cs │ │ ├── GameInProgressWindow.cs │ │ ├── GameLoadingWindow.cs │ │ ├── LoadingScreen.cs │ │ ├── MainMenu.cs │ │ ├── MainMenuDarkeningPanel.cs │ │ ├── ManualUpdateQueryWindow.cs │ │ ├── PrivacyNotification.cs │ │ ├── StatisticsWindow.cs │ │ ├── TopBar.cs │ │ ├── UpdateQueryWindow.cs │ │ ├── UpdateWindow.cs │ │ └── VideoRenderer.cs │ ├── IMessageView.cs │ ├── ISwitchable.cs │ └── Multiplayer │ │ ├── ChatListBox.cs │ │ ├── CnCNet │ │ ├── ChoiceNotificationBox.cs │ │ ├── CnCNetGameLoadingLobby.cs │ │ ├── CnCNetLobby.cs │ │ ├── CnCNetLoginWindow.cs │ │ ├── GameCreationEventArgs.cs │ │ ├── GameCreationWindow.cs │ │ ├── GlobalContextMenu.cs │ │ ├── GlobalContextMenuData.cs │ │ ├── LoadOrSaveGameOptionPresetWindow.cs │ │ ├── MapSharingConfirmationPanel.cs │ │ ├── PasswordRequestWindow.cs │ │ ├── PrivateMessageNotificationBox.cs │ │ ├── PrivateMessagingPanel.cs │ │ ├── PrivateMessagingWindow.cs │ │ ├── RecentPlayerTable.cs │ │ ├── RecentPlayerTableRightClickEventArgs.cs │ │ ├── TunnelListBox.cs │ │ └── TunnelSelectionWindow.cs │ │ ├── GameFiltersPanel.cs │ │ ├── GameInformationPanel.cs │ │ ├── GameListBox.cs │ │ ├── GameLoadingLobbyBase.cs │ │ ├── GameLobby │ │ ├── ChatBoxCommand.cs │ │ ├── CnCNetGameLobby.cs │ │ ├── CommandHandlers │ │ │ ├── CommandHandlerBase.cs │ │ │ ├── IntCommandHandler.cs │ │ │ ├── IntNotificationHandler.cs │ │ │ ├── NoParamCommandHandler.cs │ │ │ ├── NotificationHandler.cs │ │ │ └── StringCommandHandler.cs │ │ ├── CoopBriefingBox.cs │ │ ├── DropDownDataWriteMode.cs │ │ ├── GameLaunchButton.cs │ │ ├── GameLobbyBase.cs │ │ ├── GameLobbyCheckBox.cs │ │ ├── GameLobbyDropDown.cs │ │ ├── GameModeMapFilter.cs │ │ ├── GameType.cs │ │ ├── LANGameLobby.cs │ │ ├── MapCodeHelper.cs │ │ ├── MapPreviewBox.cs │ │ ├── MultiplayerGameLobby.cs │ │ ├── PlayerLocationIndicator.cs │ │ ├── SkirmishLobby.cs │ │ ├── TeamAssignmentHelper.cs │ │ ├── 游戏模式窗口.cs │ │ └── 生成随机地图窗口.cs │ │ ├── LANGameCreationWindow.cs │ │ ├── LANGameLoadingLobby.cs │ │ ├── LANLobby.cs │ │ ├── PlayerExtraOptionsPanel.cs │ │ ├── PlayerListBox.cs │ │ ├── TeamStartMappingPanel.cs │ │ └── TeamStartMappingsPanel.cs ├── Domain │ ├── DiscordHandler.cs │ ├── FinalSunSettings.cs │ ├── MainClientConstants.cs │ ├── Multiplayer │ │ ├── AllianceHolder.cs │ │ ├── CnCNet │ │ │ ├── CnCNetPlayerCountTask.cs │ │ │ ├── CnCNetTunnel.cs │ │ │ ├── ExtendedHttpClient.cs │ │ │ ├── HostedCnCNetGame.cs │ │ │ ├── MapEventArgs.cs │ │ │ ├── MapSharer.cs │ │ │ ├── SHA1EventArgs.cs │ │ │ └── TunnelHandler.cs │ │ ├── CoopHouseInfo.cs │ │ ├── CoopMapInfo.cs │ │ ├── CustomMapCache.cs │ │ ├── GameMode.cs │ │ ├── GameModeMap.cs │ │ ├── GameModeMapCollection.cs │ │ ├── GameOptionPresets.cs │ │ ├── GenericHostedGame.cs │ │ ├── LAN │ │ │ ├── ClientIntCommandHandler.cs │ │ │ ├── ClientNoParamCommandHandler.cs │ │ │ ├── ClientStringCommandHandler.cs │ │ │ ├── HostedLANGame.cs │ │ │ ├── LANClientCommandHandler.cs │ │ │ ├── LANColor.cs │ │ │ ├── LANLobbyUser.cs │ │ │ ├── LANPlayerInfo.cs │ │ │ ├── LANServerCommandHandler.cs │ │ │ ├── NetworkMessageEventArgs.cs │ │ │ ├── ServerNoParamCommandHandler.cs │ │ │ └── ServerStringCommandHandler.cs │ │ ├── Map.cs │ │ ├── MapLoader.cs │ │ ├── MapPreviewExtractor.cs │ │ ├── MultiplayerColor.cs │ │ ├── PlayerExtraOptions.cs │ │ ├── PlayerHouseInfo.cs │ │ ├── PlayerInfo.cs │ │ ├── SavedGamePlayer.cs │ │ ├── TeamStartMapping.cs │ │ └── TeamStartMappingPreset.cs │ └── SavedGame.cs ├── LocalHttpServer.cs ├── Online │ ├── Channel.cs │ ├── ChannelUser.cs │ ├── ChatMessage.cs │ ├── CnCNetGameCheck.cs │ ├── CnCNetManager.cs │ ├── CnCNetUserData.cs │ ├── Connection.cs │ ├── EventArguments │ │ ├── AttemptedServerEventArgs.cs │ │ ├── CTCPEventArgs.cs │ │ ├── ChannelCTCPEventArgs.cs │ │ ├── ChannelEventArgs.cs │ │ ├── ChannelModeEventArgs.cs │ │ ├── ChannelTopicEventArgs.cs │ │ ├── CnCNetPrivateMessageEventArgs.cs │ │ ├── ConnectionLostEventArgs.cs │ │ ├── FavoriteMapEventArgs.cs │ │ ├── GameOptionPresetEventArgs.cs │ │ ├── JoinUserEventArgs.cs │ │ ├── KickEventArgs.cs │ │ ├── MultiplayerNameRightClickedEventArgs.cs │ │ ├── PrivateCTCPEventArgs.cs │ │ ├── PrivateMessageEventArgs.cs │ │ ├── ServerMessageEventArgs.cs │ │ ├── UnreadMessageCountEventArgs.cs │ │ ├── UserAwayEventArgs.cs │ │ ├── UserListEventArgs.cs │ │ └── WhoEventArgs.cs │ ├── FileHashCalculator.cs │ ├── IConnectionManager.cs │ ├── IRCColor.cs │ ├── IRCUser.cs │ ├── IUserCollection.cs │ ├── PrivateMessageHandler.cs │ ├── PrivateMessageUser.cs │ ├── QueuedMessage.cs │ ├── QueuedMessageType.cs │ ├── RecentPlayer.cs │ ├── ReunionEntity.cs │ ├── Server.cs │ ├── SortedUserCollection.cs │ └── UnsortedUserCollection.cs ├── PreStartup.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── RA2Client.csproj.user ├── Ra2Client.csproj ├── Resources │ ├── Allied.png │ ├── Soviet.png │ ├── Yuri.png │ ├── chat_ic_lv1.png │ ├── chat_ic_lv2.png │ ├── chat_ic_lv3.png │ ├── chat_ic_lv4.png │ ├── chat_ic_lv5.png │ ├── chat_ic_lv6.png │ ├── noMapPreview.png │ ├── skillLevel1.png │ ├── skillLevel2.png │ ├── skillLevel3.png │ └── 中立.png ├── Startup.cs ├── app.manifest ├── app1.manifest └── clienticon.ico ├── README.md ├── Ra2Client.sln ├── Rampastring.Tools-2.0.6 ├── .editorconfig ├── .gitattributes ├── .github │ └── workflows │ │ └── publish.yml ├── .gitignore ├── BooleanStringStyle.cs ├── Conversions.cs ├── ExtendedStringBuilder.cs ├── FunExtensions.cs ├── IIniFile.cs ├── IIniSection.cs ├── INIProperties │ ├── BoolProperty.cs │ ├── DoubleProperty.cs │ ├── EnumProperty.cs │ ├── GenericINIProperty.cs │ ├── IIniProperty.cs │ ├── IntProperty.cs │ └── StringProperty.cs ├── IniFile.cs ├── IniParseException.cs ├── IniSection.cs ├── LICENSE.md ├── Logger.cs ├── NativeMethods.txt ├── README.md ├── Rampastring.Tools.csproj ├── Rampastring.Tools.sln ├── SafePath.cs ├── Utilities.cs └── WindowFlasher.cs ├── Rampastring.XNAUI ├── AssetLoader.cs ├── BuildAll.bat ├── EnhancedSoundEffect.cs ├── GUICreator.cs ├── Input │ ├── Cursor.cs │ ├── IIMEHandler.cs │ ├── KeyboardEventArgs.cs │ ├── KeyboardEventInput.cs │ └── RKeyboard.cs ├── LICENSE.md ├── NativeMethods.cs ├── NativeMethods.txt ├── PackAll.bat ├── PlatformSpecific │ ├── IGameWindowManager.cs │ └── WindowsGameWindowManager.cs ├── README.md ├── RMath.cs ├── Rampastring.XNAUI.csproj ├── Rampastring.XNAUI.sln ├── References │ └── XNA │ │ ├── Microsoft.Xna.Framework.Avatar.dll │ │ ├── Microsoft.Xna.Framework.Game.dll │ │ ├── Microsoft.Xna.Framework.GamerServices.dll │ │ ├── Microsoft.Xna.Framework.Graphics.dll │ │ ├── Microsoft.Xna.Framework.Input.Touch.dll │ │ ├── Microsoft.Xna.Framework.Net.dll │ │ ├── Microsoft.Xna.Framework.Storage.dll │ │ ├── Microsoft.Xna.Framework.Video.dll │ │ ├── Microsoft.Xna.Framework.Xact.dll │ │ └── Microsoft.Xna.Framework.dll ├── RenderTargetPool.cs ├── RenderTargetStack.cs ├── Renderer.cs ├── SoundPlayer.cs ├── TextParseReturnValue.cs ├── UISettings.cs ├── WindowManager.cs └── XNAControls │ ├── Callback.cs │ ├── ControlDrawMode.cs │ ├── IControlINIAttributeParser.cs │ ├── MouseEventArgs.cs │ ├── XNAButton.cs │ ├── XNACheckBox.cs │ ├── XNAContextMenu.cs │ ├── XNAControl.cs │ ├── XNADropDown.cs │ ├── XNADropDownItem.cs │ ├── XNAIndicator.cs │ ├── XNALabel.cs │ ├── XNALinkLabel.cs │ ├── XNAListBox.cs │ ├── XNAListBoxItem.cs │ ├── XNAMultiColumnListBox.cs │ ├── XNAPanel.cs │ ├── XNAPasswordBox.cs │ ├── XNAProgressBar.cs │ ├── XNARatingBox.cs │ ├── XNAScrollBar.cs │ ├── XNASuggestionTextBox.cs │ ├── XNATabControl.cs │ ├── XNATextBlock.cs │ ├── XNATextBox.cs │ ├── XNATextRenderer.cs │ ├── XNATimerControl.cs │ └── XNATrackbar.cs ├── RandomMapGenerator ├── AbstractMapMember.cs ├── Constants.cs ├── MapFormat.cs ├── Mapfile.cs ├── NonTileObjects │ ├── Aircraft.cs │ ├── Infantry.cs │ ├── Smudge.cs │ ├── Structure.cs │ ├── Terrain.cs │ ├── Unit.cs │ └── Waypoint.cs ├── Options.cs ├── RandomMapGenerator.csproj ├── RandomMapGenerator.sln ├── Tile │ ├── AbstractMapUnit.cs │ ├── AbstractTile.cs │ ├── AbstractTileType.cs │ ├── FailureAbstractMapUnitRecord.cs │ └── TileEnum.cs ├── WorkingMap.cs └── 随机地图生成.cs ├── Reunion ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── Reunion.csproj ├── ZIP.cs └── clienticon.ico ├── cncnetchatlobby.png └── cncnetgamelobby.png /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 3 | ################################################################################ 4 | 5 | /.vs/ 6 | /.idea/ 7 | /Bin 8 | /ClientCore/bin 9 | /ClientCore/obj 10 | /ClientGUI/bin 11 | /ClientGUI/obj 12 | /DTAConfig/bin 13 | /ReunionServer/ReunionServer/bin 14 | /ReunionServer/ReunionServer/obj 15 | /ReunionServer/ReunionShareModel/bin 16 | /ReunionServer/ReunionShareModel/obj 17 | /DTAConfig/obj 18 | /DTAConfig/bin 19 | /Localization/bin 20 | /Localization/obj 21 | /Ra2Client/obj 22 | /Ra2Client/bin 23 | /Rampastring.XNAUI/.vs 24 | /Rampastring.XNAUI/bin 25 | /Rampastring.XNAUI/obj 26 | /Reunion/.vs 27 | /Reunion/obj 28 | /Reunion/bin 29 | /ClientUpdater/obj 30 | /ClientUpdater/bin 31 | /e -i HEAD~3 32 | *.tmp 33 | *.log 34 | /RandomMapGenerator/obj 35 | /RandomMapGenerator/bin 36 | /Render/CNCMaps.Engine/obj 37 | /Render/CNCMaps.FileFormats/obj 38 | /Render/CNCMaps.Shared/obj 39 | -------------------------------------------------------------------------------- /ClientCore/ClientConfiguration.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/ClientConfiguration.cs -------------------------------------------------------------------------------- /ClientCore/CnCNet5/CnCNetGame.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework.Graphics; 2 | 3 | namespace ClientCore.CnCNet5 4 | { 5 | /// 6 | /// A class for games supported on CnCNet (DTA, TI, TS, RA1/2, etc.) 7 | /// 8 | public class CnCNetGame 9 | { 10 | /// 11 | /// The name of the game that is displayed on the user-interface. 12 | /// 13 | public string UIName { get; set; } 14 | 15 | /// 16 | /// The internal name (suffix) of the game. 17 | /// 18 | public string InternalName { get; set; } 19 | 20 | /// 21 | /// The IRC chat channel ID of the game. 22 | /// 23 | public string ChatChannel { get; set; } 24 | 25 | /// 26 | /// The IRC game broadcasting channel ID of the game. 27 | /// 28 | public string GameBroadcastChannel { get; set; } 29 | 30 | /// 31 | /// The executable name of the game's client. 32 | /// 33 | public string ClientExecutableName { get; set; } 34 | 35 | public Texture2D Texture { get; set; } 36 | 37 | /// 38 | /// The location where to read the game's installation path from the registry. 39 | /// 40 | public string RegistryInstallPath { get; set; } 41 | 42 | private bool supported = true; 43 | 44 | /// 45 | /// Determines if the game is properly supported by this client. 46 | /// Defaults to true. 47 | /// 48 | public bool Supported 49 | { 50 | get { return supported; } 51 | set { supported = value; } 52 | } 53 | 54 | /// 55 | /// If true, the client should always be connected to this game's chat channel. 56 | /// 57 | public bool AlwaysEnabled { get; set; } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ClientCore/Entity/Badge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public class Badge 10 | { 11 | public int id { get; set; } 12 | public string name { get; set; } 13 | public int side { get; set; } 14 | public int level { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ClientCore/Entity/BadgeVo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public class BadgeVo 10 | { 11 | public int exp { get; set; } 12 | 13 | public int nextLevelExp { get; set; } 14 | 15 | public int level { get; set; } 16 | 17 | public string badgeName { get; set; } 18 | 19 | public List canUseBadges { get; set; } 20 | 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ClientCore/Entity/Component.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DTAConfig.Entity 8 | { 9 | public record class Component 10 | { 11 | public int id { get; set; } 12 | 13 | public string name { get; set; } 14 | 15 | public string description { get; set; } 16 | 17 | public int type { get; set; } 18 | public string tags { get; set; } 19 | 20 | public string file { get; set; } 21 | 22 | public long size { get; set; } 23 | 24 | public string hash { get; set; } 25 | 26 | public string uploadTime { get; set; } 27 | 28 | public int uploadUser { get; set; } 29 | 30 | public string passTime { get; set; } 31 | 32 | public string uploadUserName { get; set; } 33 | 34 | public string typeName { get; set; } 35 | 36 | public long downCount { get; set; } 37 | 38 | public string version { get; set; } 39 | public string apply { get; set; } 40 | public string author { get; set; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ClientCore/Entity/ComponentVo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Xna.Framework; 4 | 5 | namespace DTAConfig.Entity; 6 | 7 | public class ComponentVo 8 | { 9 | public int id { get; set; } // 组件ID 10 | public string name { get; set; } // 组件名称 11 | 12 | public string author { get; set; } // 作者 13 | 14 | public string version { get; set; } // 版本号 15 | 16 | public string file { get; set; } // 组件压缩包 17 | 18 | public int type { get; set; } // 类型 19 | public string typeName { get; set; } 20 | 21 | public long size { get; set; } // 文件大小 22 | 23 | public string hash { get; set; } // 哈希值 24 | 25 | public long downCount { get; set; } 26 | 27 | public string uploadTime { get; set; } 28 | 29 | public int uploadUser { get; set; } 30 | public string uploadUserName { get; set; } 31 | 32 | public List apply { get; set; } 33 | 34 | public string tags { get; set; } 35 | 36 | public string description { get; set; } 37 | 38 | } 39 | 40 | public struct StateItem 41 | { 42 | public int Code { get; set; } 43 | 44 | public string Text { get; set; } 45 | 46 | public Color TextColor { get; set; } 47 | } -------------------------------------------------------------------------------- /ClientCore/Entity/Maps.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public class Maps 10 | { 11 | public string img { get; set; } = null; 12 | public string csf { get; set; } = null; 13 | public int id { get; set; } = 0; 14 | public string name { get; set; } = null; 15 | public string maxPlayers { get; set; } = null; 16 | public string author { get; set; } = null; 17 | public int type { get; set; } = 0; 18 | public string base64 { get; set; } = null; 19 | public string file { get; set; } = null; 20 | public string createTime { get; set; } = null; 21 | public int createUser { get; set; } = 0; 22 | public int enable { get; set; } = 0; 23 | public long downCount { get; set; } = 0; 24 | public double score { get; set; } = 0.0; 25 | public string description { get; set; } = ""; 26 | public string uploadUserName { get; set; } = ""; 27 | 28 | public string typeName { get; set; } = ""; 29 | public string rules { get; set; } 30 | 31 | public string enemyHouse { get; set; } = ""; 32 | 33 | public string allyHouse { get; set; } = ""; 34 | 35 | public Maps() { } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ClientCore/Entity/Music.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DTAConfig.Entity 8 | { 9 | public record Music 10 | { 11 | /// 12 | /// 音乐名 13 | /// 14 | public string Name { get; set; } 15 | public string Section { get; set; } 16 | /// 17 | /// 中文名 18 | /// 19 | public string CName { get; set; } 20 | 21 | /// 22 | /// 大小 23 | /// 24 | public string Size { get; set; } 25 | /// 26 | /// 音乐时长 27 | /// 28 | public string Length { get; set; } 29 | /// 30 | /// 音乐文件 31 | /// 32 | public string Sound { get; set; } 33 | public string Scenario { get; set; } 34 | /// 35 | /// 能听到的阵营 36 | /// 37 | public string Side { get; set; } 38 | /// 39 | /// 是否始终循环 40 | /// 41 | public string Repeat { get; set; } 42 | public string Normal { get; set; } 43 | public string Path { get; set; } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ClientCore/Entity/Page.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public class Page 10 | { 11 | public List records { get; set; } // 当前页的记录 12 | public long total { get; set; } // 总记录数 13 | public int size { get; set; } // 每页大小 14 | public int current { get; set; } // 当前页码 15 | public int pages { get; set; } // 总页数 16 | 17 | public Page() { } 18 | 19 | //public Page(List records, long total, int size, int current, int pages) 20 | //{ 21 | // records = records; 22 | // total = total; 23 | // size = size; 24 | // current = current; 25 | // pages = pages; 26 | //} 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ClientCore/Entity/PassDto.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | namespace ClientCore.Entity 4 | { 5 | public record class PassDto 6 | { 7 | public int userId { get; set; } 8 | public int score { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ClientCore/Entity/QuestionBank.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DTAConfig.Entity 8 | { 9 | public record class QuestionBank 10 | { 11 | public int? id { get; set; } 12 | public string name { get; set; } = ""; 13 | public string problem { get; set; } = ""; 14 | public string options { get; set; } = ""; 15 | public int answer { get; set; } = 0; 16 | public int difficulty { get; set; } = 0; 17 | public string type { get; set; } = ""; 18 | public int enable { get; set; } = 0; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ClientCore/Entity/Score.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public record class Score 10 | { 11 | public string name { get; set; } 12 | public double score { get; set; } 13 | public string brief { get; set; } 14 | public string missionPack { get; set; } 15 | public int total { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ClientCore/Entity/Thank.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public record class Thank 10 | { 11 | public int id { get; set; } 12 | public string author { get; set; } 13 | public string content { get; set; } 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ClientCore/Entity/Updater.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public record class Updater 10 | { 11 | public int id { get; set; } 12 | public string version { get; set; } 13 | public string file { get; set; } 14 | public string hash { get; set; } 15 | public long size { get; set; } 16 | public string log { get; set; } 17 | public string channel { get; set; } 18 | public string updateTime { get; set; } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ClientCore/Entity/UpdaterServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public readonly record struct UpdaterServer( 10 | int? id, 11 | string name, 12 | int type, 13 | string location, 14 | string url 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /ClientCore/Entity/User.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | namespace ClientCore.Entity 4 | { 5 | public record class User 6 | { 7 | public int id { get; set; } 8 | public string username { get; set; } = string.Empty; 9 | public string password { get; set; } = string.Empty; 10 | public string allow_time { get; set; } = string.Empty; 11 | public string email { get; set; } = string.Empty; 12 | public string role { get; set; } = string.Empty; 13 | public string tag { get; set; } = string.Empty; 14 | public int side { get; set; } = 3; 15 | public int badge { get; set; } = 0; 16 | public string mac { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ClientCore/Entity/badgeDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClientCore.Entity 8 | { 9 | public class BadgeDto 10 | { 11 | public int userId { get; set; } 12 | public int badgeId { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ClientCore/Enums/AllowPrivateMessagesFromEnum.cs: -------------------------------------------------------------------------------- 1 | namespace ClientCore.Enums 2 | { 3 | public enum AllowPrivateMessagesFromEnum 4 | { 5 | All = 1, 6 | Friends = 2, 7 | None = 3 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ClientCore/Enums/ResResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DTAConfig.Entity 8 | { 9 | public record ResResult 10 | { 11 | public string message { get; set; } 12 | public string code { get; set; } 13 | public T data { get; set; } 14 | 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ClientCore/Enums/SortDirection.cs: -------------------------------------------------------------------------------- 1 | namespace ClientCore.Enums 2 | { 3 | public enum SortDirection 4 | { 5 | None = 0, 6 | Asc = 1, 7 | Desc = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ClientCore/Extensions/EnumExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClientCore.Extensions 4 | { 5 | public static class EnumExtensions 6 | { 7 | public static T Next(this T src) where T : Enum 8 | { 9 | T[] Arr = GetValues(src); 10 | int nextIndex = Array.IndexOf(Arr, src) + 1; 11 | return Arr.Length == nextIndex ? Arr[0] : Arr[nextIndex]; 12 | } 13 | 14 | public static T First(this T src) where T : Enum 15 | { 16 | return GetValues(src)[0]; 17 | } 18 | 19 | private static T[] GetValues(T src) where T : Enum 20 | { 21 | return (T[])Enum.GetValues(src.GetType()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ClientCore/Extensions/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace ClientCore.Extensions; 5 | 6 | public static class EnumerableExtensions 7 | { 8 | /// 9 | /// Converts an enumerable to a matrix of items with a max number of items per column. 10 | /// The matrix is built column by column, left to right. 11 | /// 12 | /// the enumerable to convert 13 | /// the max number of items per column 14 | /// 15 | /// 16 | public static List> ToMatrix(this IEnumerable enumerable, int maxPerColumn) 17 | { 18 | var list = enumerable.ToList(); 19 | return list.Aggregate(new List>(), (matrix, item) => 20 | { 21 | int index = list.IndexOf(item); 22 | int column = (index / maxPerColumn); 23 | List columnList = matrix.Count <= column ? new List() : matrix[column]; 24 | if (columnList.Count == 0) 25 | matrix.Add(columnList); 26 | 27 | columnList.Add(item); 28 | return matrix; 29 | }); 30 | } 31 | } -------------------------------------------------------------------------------- /ClientCore/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClientCore.Extensions 4 | { 5 | public static class StringExtensions 6 | { 7 | public static string GetLink(this string text) 8 | { 9 | if (string.IsNullOrWhiteSpace(text)) 10 | return null; 11 | 12 | int index = text.IndexOf("http://", StringComparison.Ordinal); 13 | if (index == -1) 14 | index = text.IndexOf("ftp://", StringComparison.Ordinal); 15 | if (index == -1) 16 | index = text.IndexOf("https://", StringComparison.Ordinal); 17 | 18 | if (index == -1) 19 | return null; // No link found 20 | 21 | string link = text.Substring(index); 22 | return link.Split(' ')[0]; // Nuke any words coming after the link 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/Cache.cs: -------------------------------------------------------------------------------- 1 | #region Copyright & License Information 2 | /* 3 | * Copyright (c) The OpenRA Developers and Contributors 4 | * This file is part of OpenRA, which is free software. It is made 5 | * available to you under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation, either version 3 of 7 | * the License, or (at your option) any later version. For more 8 | * information, see COPYING. 9 | */ 10 | #endregion 11 | 12 | using Localization.Tools; 13 | using System; 14 | using System.Collections.Generic; 15 | 16 | namespace OpenRA.Primitives 17 | { 18 | public class Cache : IReadOnlyDictionary 19 | { 20 | readonly Dictionary cache; 21 | readonly Func loader; 22 | 23 | public Cache(Func loader, IEqualityComparer c) 24 | { 25 | ArgumentNullException.ThrowIfNull(loader); 26 | 27 | this.loader = loader; 28 | cache = new Dictionary(c); 29 | } 30 | 31 | public Cache(Func loader) 32 | : this(loader, EqualityComparer.Default) { } 33 | 34 | public U this[T key] => cache.GetOrAdd(key, loader); 35 | 36 | public bool ContainsKey(T key) { return cache.ContainsKey(key); } 37 | public bool TryGetValue(T key, out U value) { return cache.TryGetValue(key, out value); } 38 | public int Count => cache.Count; 39 | public void Clear() { cache.Clear(); } 40 | 41 | public ICollection Keys => cache.Keys; 42 | public ICollection Values => cache.Values; 43 | 44 | IEnumerable IReadOnlyDictionary.Keys => cache.Keys; 45 | 46 | IEnumerable IReadOnlyDictionary.Values => cache.Values; 47 | 48 | public IEnumerator> GetEnumerator() { return cache.GetEnumerator(); } 49 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/Format5.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DTAConfig.Entity 4 | { 5 | public class Format5 { 6 | public static unsafe uint DecodeInto(byte[] src, byte[] dest, int format = 5) { 7 | fixed (byte* pr = src, pw = dest) { 8 | byte* r = pr, w = pw; 9 | byte* w_end = w + dest.Length; 10 | 11 | while (w < w_end) { 12 | ushort size_in = *(ushort*)r; 13 | r += 2; 14 | uint size_out = *(ushort*)r; 15 | r += 2; 16 | 17 | if (size_in == 0 || size_out == 0) 18 | break; 19 | 20 | if (format == 80) 21 | Format80.DecodeInto(r, w); 22 | else 23 | MiniLZO.Decompress(r, size_in, w, ref size_out); 24 | r += size_in; 25 | w += size_out; 26 | } 27 | return (uint)(w - pw); 28 | } 29 | } 30 | 31 | public static byte[] EncodeSection(byte[] s) { 32 | return MiniLZO.Compress(s); 33 | } 34 | 35 | public static byte[] Encode(byte[] source, int format) { 36 | var dest = new byte[source.Length * 2]; 37 | var src = new MemoryFile(source); 38 | 39 | int w = 0; 40 | while (!src.Eof) { 41 | var cb_in = (short)Math.Min(src.Remaining, 8192); 42 | var chunk_in = src.Read(cb_in); 43 | var chunk_out = format == 80 ? Format80.Encode(chunk_in) : EncodeSection(chunk_in); 44 | uint cb_out = (ushort)chunk_out.Length; 45 | 46 | Array.Copy(BitConverter.GetBytes(cb_out), 0, dest, w, 2); 47 | w += 2; 48 | Array.Copy(BitConverter.GetBytes(cb_in), 0, dest, w, 2); 49 | w += 2; 50 | Array.Copy(chunk_out, 0, dest, w, chunk_out.Length); 51 | w += chunk_out.Length; 52 | } 53 | Array.Resize(ref dest, w); 54 | return dest; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/IPackage.cs: -------------------------------------------------------------------------------- 1 | #region Copyright & License Information 2 | /* 3 | * Copyright (c) The OpenRA Developers and Contributors 4 | * This file is part of OpenRA, which is free software. It is made 5 | * available to you under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation, either version 3 of 7 | * the License, or (at your option) any later version. For more 8 | * information, see COPYING. 9 | */ 10 | #endregion 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.IO; 15 | 16 | namespace OpenRA.FileSystem 17 | { 18 | public interface IPackageLoader 19 | { 20 | /// 21 | /// Attempt to parse a stream as this type of package. 22 | /// If successful, the loader is expected to take ownership of `s` and dispose it once done. 23 | /// If unsuccessful, the loader is expected to return the stream position to where it started. 24 | /// 25 | bool TryParsePackage(Stream s, string filename, FileSystem context, out IReadOnlyPackage package); 26 | } 27 | 28 | public interface IReadOnlyPackage : IDisposable 29 | { 30 | string Name { get; } 31 | IEnumerable Contents { get; } 32 | Stream GetStream(string filename); 33 | bool Contains(string filename); 34 | IReadOnlyPackage OpenPackage(string filename, FileSystem context); 35 | } 36 | 37 | public interface IReadWritePackage : IReadOnlyPackage 38 | { 39 | void Update(string filename, byte[] contents); 40 | void Delete(string filename); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/IsoTile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DTAConfig.Entity 8 | { 9 | public class MapObject 10 | { 11 | public IsoTile Tile; 12 | } 13 | 14 | public class NamedMapObject : MapObject 15 | { 16 | public string Name { get; set; } 17 | } 18 | 19 | public class NumberedMapObject : MapObject 20 | { 21 | public virtual int Number { get; set; } 22 | } 23 | 24 | public class IsoTile : NumberedMapObject 25 | { 26 | public ushort Dx; 27 | public ushort Dy; 28 | public ushort Rx; 29 | public ushort Ry; 30 | public byte Z; 31 | public int TileNum; 32 | public byte SubTile; 33 | public byte IceGrowth; 34 | 35 | public IsoTile(ushort p1, ushort p2, ushort rx, ushort ry, byte z, int tilenum, byte subtile, byte icegrowth) 36 | { 37 | Dx = p1; 38 | Dy = p2; 39 | Rx = rx; 40 | Ry = ry; 41 | Z = z; 42 | TileNum = tilenum; 43 | SubTile = subtile; 44 | IceGrowth = icegrowth; 45 | } 46 | 47 | public List ToMapPack5Entry() 48 | { 49 | var ret = new List(); 50 | ret.AddRange(BitConverter.GetBytes(Rx)); 51 | ret.AddRange(BitConverter.GetBytes(Ry)); 52 | ret.AddRange(BitConverter.GetBytes(TileNum)); 53 | ret.Add(SubTile); 54 | ret.Add(Z); 55 | ret.Add(IceGrowth); 56 | return ret; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/MemoryFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DTAConfig.Entity 9 | { 10 | public class MemoryFile : VirtualFile 11 | { 12 | 13 | public MemoryFile(byte[] buffer, bool isBuffered = true) : 14 | base(new MemoryStream(buffer), "MemoryFile", 0, buffer.Length, isBuffered) 15 | { } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/MixFile.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/FileFormats/MixFile.cs -------------------------------------------------------------------------------- /ClientCore/FileFormats/TwoDimensionalEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DTAConfig.Entity 9 | { 10 | public class TwoDimensionalEnumerator : IEnumerator 11 | { 12 | T[,] array; 13 | int curX, curY; 14 | public TwoDimensionalEnumerator(T[,] array) 15 | { 16 | this.array = array; 17 | Reset(); 18 | } 19 | public bool MoveNext() 20 | { 21 | curX++; 22 | if (curX == array.GetLength(0)) 23 | { 24 | curX = 0; 25 | curY++; 26 | } 27 | return curY < array.GetLength(1); 28 | } 29 | public void Reset() 30 | { 31 | curX = -1; 32 | curY = 0; 33 | } 34 | T IEnumerator.Current 35 | { 36 | get 37 | { 38 | return array[curX, curY]; 39 | } 40 | } 41 | object IEnumerator.Current 42 | { 43 | get { return array[curX, curY]; } 44 | } 45 | public void Dispose() { } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/XccGlobalDatabase.cs: -------------------------------------------------------------------------------- 1 | #region Copyright & License Information 2 | /* 3 | * Copyright (c) The OpenRA Developers and Contributors 4 | * This file is part of OpenRA, which is free software. It is made 5 | * available to you under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation, either version 3 of 7 | * the License, or (at your option) any later version. For more 8 | * information, see COPYING. 9 | */ 10 | #endregion 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.IO; 15 | 16 | namespace OpenRA.Mods.Cnc.FileFormats 17 | { 18 | public sealed class XccGlobalDatabase : IDisposable 19 | { 20 | public readonly string[] Entries; 21 | readonly Stream s; 22 | 23 | public XccGlobalDatabase(Stream stream) 24 | { 25 | s = stream; 26 | 27 | var entries = new List(); 28 | var chars = new char[32]; 29 | while (s.Peek() > -1) 30 | { 31 | var count = s.ReadInt32(); 32 | entries.Capacity += count; 33 | for (var i = 0; i < count; i++) 34 | { 35 | // Read filename 36 | byte c; 37 | var charsIndex = 0; 38 | while ((c = s.ReadUInt8()) != 0) 39 | { 40 | if (charsIndex >= chars.Length) 41 | Array.Resize(ref chars, chars.Length * 2); 42 | chars[charsIndex++] = (char)c; 43 | } 44 | 45 | entries.Add(new string(chars, 0, charsIndex)); 46 | 47 | // Skip comment 48 | while (s.ReadUInt8() != 0) { } 49 | } 50 | } 51 | 52 | Entries = entries.ToArray(); 53 | } 54 | 55 | public void Dispose() 56 | { 57 | s.Dispose(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ClientCore/FileFormats/XccLocalDatabase.cs: -------------------------------------------------------------------------------- 1 | #region Copyright & License Information 2 | /* 3 | * Copyright (c) The OpenRA Developers and Contributors 4 | * This file is part of OpenRA, which is free software. It is made 5 | * available to you under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation, either version 3 of 7 | * the License, or (at your option) any later version. For more 8 | * information, see COPYING. 9 | */ 10 | #endregion 11 | 12 | using System.Collections.Generic; 13 | using System.IO; 14 | using System.Linq; 15 | using System.Text; 16 | 17 | namespace OpenRA.Mods.Cnc.FileFormats 18 | { 19 | public class XccLocalDatabase 20 | { 21 | public readonly string[] Entries; 22 | public XccLocalDatabase(Stream s) 23 | { 24 | // Skip unnecessary header data 25 | s.Seek(48, SeekOrigin.Begin); 26 | var reader = new BinaryReader(s); 27 | var count = reader.ReadInt32(); 28 | Entries = new string[count]; 29 | var chars = new List(); 30 | for (var i = 0; i < count; i++) 31 | { 32 | char c; 33 | while ((c = reader.ReadChar()) != 0) 34 | chars.Add(c); 35 | 36 | Entries[i] = new string(chars.ToArray()); 37 | chars.Clear(); 38 | } 39 | } 40 | 41 | public XccLocalDatabase(IEnumerable filenames) 42 | { 43 | Entries = filenames.ToArray(); 44 | } 45 | 46 | public byte[] Data() 47 | { 48 | var data = new MemoryStream(); 49 | using (var writer = new BinaryWriter(data)) 50 | { 51 | writer.Write(Encoding.ASCII.GetBytes("XCC by Olaf van der Spek")); 52 | writer.Write(new byte[] { 0x1A, 0x04, 0x17, 0x27, 0x10, 0x19, 0x80, 0x00 }); 53 | 54 | writer.Write(Entries.Sum(e => e.Length) + Entries.Length + 52); // Size 55 | writer.Write(0); // Type 56 | writer.Write(0); // Version 57 | writer.Write(0); // Game/Format (0 == TD) 58 | writer.Write(Entries.Length); // Entries 59 | foreach (var e in Entries) 60 | { 61 | writer.Write(Encoding.ASCII.GetBytes(e)); 62 | writer.Write((byte)0); 63 | } 64 | } 65 | 66 | return data.ToArray(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ClientCore/FileLockedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace ClientCore 9 | { 10 | public class FileLockedException : IOException 11 | { 12 | // 默认构造函数 13 | public FileLockedException() 14 | : base("文件操作失败,文件可能被占用。") 15 | { 16 | } 17 | 18 | // 带有自定义消息的构造函数 19 | public FileLockedException(string message) 20 | : base(message) 21 | { 22 | } 23 | 24 | // 带有自定义消息和内部异常的构造函数,用于异常链 25 | public FileLockedException(string message, Exception innerException) 26 | : base(message, innerException) 27 | { 28 | } 29 | 30 | // 可以添加额外的属性或方法来提供有关文件操作的更多信息 31 | // 例如,添加一个属性来指示哪个文件被占用 32 | public string LockedFilePath { get; set; } 33 | 34 | // 构造函数,其中包括被锁定文件的路径 35 | public FileLockedException(string message, string lockedFilePath) 36 | : this(message) 37 | { 38 | LockedFilePath = lockedFilePath; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ClientCore/LoadingScreenController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClientCore 4 | { 5 | public static class LoadingScreenController 6 | { 7 | public static string GetLoadScreenName(string sideId) 8 | { 9 | int resHeight = UserINISettings.Instance.IngameScreenHeight; 10 | 11 | string loadingScreenName = ProgramConstants.BASE_RESOURCE_PATH + "l"; 12 | 13 | if (resHeight < 480) 14 | loadingScreenName += "400"; 15 | else if (resHeight < 600) 16 | loadingScreenName += "480"; 17 | else 18 | loadingScreenName += "600"; 19 | 20 | loadingScreenName = loadingScreenName + "s" + sideId; 21 | Random random = new Random(); 22 | int randomInt = random.Next(1, 1 + ClientConfiguration.Instance.LoadingScreenCount); 23 | 24 | return loadingScreenName + Convert.ToString(randomInt) + ".pcx"; 25 | //return "l600s01.pcx"; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ClientCore/OSVersion.cs: -------------------------------------------------------------------------------- 1 | public enum OSVersion 2 | { 3 | UNKNOWN, 4 | Windows2000, 5 | WindowsXP, 6 | WindowsXP_SERVER2003_SERVER2003R2, 7 | WindowsVista_SERVER2008, 8 | Windows7_SERVER2008R2, 9 | Windows8_SERVER2012, 10 | Windows8_1_SERVER2012R2, 11 | Windows10_1507_LTSB2015, 12 | Windows10_1511, 13 | Windows10_1607_LTSB2016_SERVER2016, 14 | Windows10_1703, 15 | Windows10_1709, 16 | Windows10_1803, 17 | Windows10_1809_LTSC2019_SERVER2019, 18 | Windows10_1903, 19 | Windows10_1909, 20 | Windows10_2004, 21 | Windows10_20H2, 22 | Windows10_21H1, 23 | Windows10_21H2_LTSC2021, 24 | Windows10_22H2_2009, 25 | Windows10_SERVER2022, 26 | Windows11_21H2, 27 | Windows11_22H2, 28 | Windows11_23H2, 29 | Windows11_23H2_Beta, 30 | Windows11_24H2_LTSC2024_SERVER2025, 31 | Windows11_24H2_Beta, 32 | Windows11_24H2_Dev, 33 | Windows11_25H2, 34 | Windows11_30H1, 35 | Experimental_Version_Of_Windows, 36 | UNIX 37 | } -------------------------------------------------------------------------------- /ClientCore/PlatformShim/EncodingExt.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace ClientCore.PlatformShim; 4 | 5 | public static class EncodingExt 6 | { 7 | static EncodingExt() 8 | { 9 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 10 | 11 | ANSI = Encoding.GetEncoding(0); 12 | } 13 | 14 | /// 15 | /// Gets the legacy ANSI encoding (not Windows-1252 and also not any specific encoding). 16 | /// ANSI doesn't mean a specific codepage, it means the default non-Unicode codepage which can be changed from Control Panel. 17 | /// 18 | public static Encoding ANSI { get; } 19 | } -------------------------------------------------------------------------------- /ClientCore/ProcessLauncher.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace ClientCore 4 | { 5 | public static class ProcessLauncher 6 | { 7 | public static void StartShellProcess(string commandLine) 8 | { 9 | using var _ = Process.Start(new ProcessStartInfo 10 | { 11 | FileName = commandLine, 12 | UseShellExecute = true 13 | }); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /ClientCore/Resources/cncneticon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/cncneticon.png -------------------------------------------------------------------------------- /ClientCore/Resources/cncricon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/cncricon.png -------------------------------------------------------------------------------- /ClientCore/Resources/d2kicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/d2kicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/dtaicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/dtaicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/moicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/moicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/raicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/raicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/reicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/reicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/rricon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/rricon.png -------------------------------------------------------------------------------- /ClientCore/Resources/ssicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/ssicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/tdicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/tdicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/tiicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/tiicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/tsicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/tsicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/unknownicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/unknownicon.png -------------------------------------------------------------------------------- /ClientCore/Resources/yricon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/ClientCore/Resources/yricon.png -------------------------------------------------------------------------------- /ClientCore/Settings/BoolSetting.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | 3 | namespace ClientCore.Settings 4 | { 5 | public class BoolSetting : INISetting 6 | { 7 | public BoolSetting(IniFile iniFile, string iniSection, string iniKey, bool defaultValue) 8 | : base(iniFile, iniSection, iniKey, defaultValue) 9 | { 10 | } 11 | 12 | protected override bool Get() 13 | { 14 | return IniFile.GetBooleanValue(IniSection, IniKey, DefaultValue); 15 | } 16 | 17 | protected override void Set(bool value) 18 | { 19 | IniFile.SetBooleanValue(IniSection, IniKey, value); 20 | } 21 | 22 | public override void Write() 23 | { 24 | IniFile.SetBooleanValue(IniSection, IniKey, Get()); 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return Get().ToString(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ClientCore/Settings/DoubleSetting.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | 3 | namespace ClientCore.Settings 4 | { 5 | public class DoubleSetting : INISetting 6 | { 7 | public DoubleSetting(IniFile iniFile, string iniSection, string iniKey, double defaultValue) 8 | : base(iniFile, iniSection, iniKey, defaultValue) 9 | { 10 | } 11 | 12 | protected override double Get() 13 | { 14 | return IniFile.GetDoubleValue(IniSection, IniKey, DefaultValue); 15 | } 16 | 17 | protected override void Set(double value) 18 | { 19 | IniFile.SetDoubleValue(IniSection, IniKey, value); 20 | } 21 | 22 | public override void Write() 23 | { 24 | IniFile.SetDoubleValue(IniSection, IniKey, Get()); 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return Get().ToString(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ClientCore/Settings/IIniSetting.cs: -------------------------------------------------------------------------------- 1 | namespace ClientCore.Settings 2 | { 3 | /// 4 | /// A dummy interface for checking for INISetting in reflection. 5 | /// 6 | interface IIniSetting 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ClientCore/Settings/INISetting.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | 3 | namespace ClientCore.Settings 4 | { 5 | /// 6 | /// A base class for an INI setting. 7 | /// 8 | public abstract class INISetting : IIniSetting 9 | { 10 | public INISetting(IniFile iniFile, string iniSection, string iniKey, 11 | T defaultValue) 12 | { 13 | IniFile = iniFile; 14 | IniSection = iniSection; 15 | IniKey = iniKey; 16 | DefaultValue = defaultValue; 17 | } 18 | 19 | public static implicit operator T(INISetting iniSetting) 20 | { 21 | return iniSetting.Get(); 22 | } 23 | 24 | public void SetIniFile(IniFile iniFile) 25 | { 26 | IniFile = iniFile; 27 | } 28 | 29 | protected IniFile IniFile { get; private set; } 30 | protected string IniSection { get; private set; } 31 | protected string IniKey { get; private set; } 32 | protected T DefaultValue { get; private set; } 33 | 34 | public T Value 35 | { 36 | get { return Get(); } 37 | set { Set(value); } 38 | } 39 | 40 | /// 41 | /// Writes the default value of this setting to the INI file if no value 42 | /// for the setting is currently specified in the INI file. 43 | /// 44 | public void SetDefaultIfNonexistent() 45 | { 46 | if (!IniFile.KeyExists(IniSection, IniKey)) 47 | Set(DefaultValue); 48 | } 49 | 50 | protected abstract T Get(); 51 | 52 | protected abstract void Set(T value); 53 | 54 | public abstract void Write(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ClientCore/Settings/IntRangeSetting.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | 3 | namespace ClientCore.Settings 4 | { 5 | /// 6 | /// Similar to IntSetting, this setting forces a min and max value upon getting and setting. 7 | /// 8 | public class IntRangeSetting : IntSetting 9 | { 10 | private readonly int MinValue; 11 | private readonly int MaxValue; 12 | 13 | public IntRangeSetting(IniFile iniFile, string iniSection, string iniKey, int defaultValue, int minValue, int maxValue) : base(iniFile, iniSection, iniKey, defaultValue) 14 | { 15 | MinValue = minValue; 16 | MaxValue = maxValue; 17 | } 18 | 19 | /// 20 | /// Checks the validity of the value. If the value is invalid, return the default value of this setting. 21 | /// Otherwise, return the set value. 22 | /// 23 | /// 24 | /// 25 | private int NormalizeValue(int value) 26 | { 27 | return InvalidValue(value) ? DefaultValue : value; 28 | } 29 | 30 | private bool InvalidValue(int value) 31 | { 32 | return value < MinValue || value > MaxValue; 33 | } 34 | 35 | protected override int Get() 36 | { 37 | return NormalizeValue(IniFile.GetIntValue(IniSection, IniKey, DefaultValue)); 38 | } 39 | 40 | protected override void Set(int value) 41 | { 42 | IniFile.SetIntValue(IniSection, IniKey, NormalizeValue(value)); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ClientCore/Settings/IntSetting.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | 3 | namespace ClientCore.Settings 4 | { 5 | public class IntSetting : INISetting 6 | { 7 | public IntSetting(IniFile iniFile, string iniSection, string iniKey, int defaultValue) 8 | : base(iniFile, iniSection, iniKey, defaultValue) 9 | { 10 | } 11 | 12 | protected override int Get() 13 | { 14 | return IniFile.GetIntValue(IniSection, IniKey, DefaultValue); 15 | } 16 | 17 | protected override void Set(int value) 18 | { 19 | IniFile.SetIntValue(IniSection, IniKey, value); 20 | } 21 | 22 | public override void Write() 23 | { 24 | IniFile.SetIntValue(IniSection, IniKey, Get()); 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return Get().ToString(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ClientCore/Settings/StringListSetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Rampastring.Tools; 5 | 6 | namespace ClientCore.Settings 7 | { 8 | /// 9 | /// This is a setting that can be stored as a comma separated list of strings. 10 | /// 11 | public class StringListSetting : INISetting> 12 | { 13 | public StringListSetting(IniFile iniFile, string iniSection, string iniKey, List defaultValue) : base(iniFile, iniSection, iniKey, defaultValue) 14 | { 15 | } 16 | 17 | protected override List Get() 18 | { 19 | string value = IniFile.GetStringValue(IniSection, IniKey, ""); 20 | return string.IsNullOrWhiteSpace(value) ? DefaultValue : value.Split(',').ToList(); 21 | } 22 | 23 | protected override void Set(List value) 24 | { 25 | IniFile.SetStringValue(IniSection, IniKey, string.Join(",", value)); 26 | } 27 | 28 | public override void Write() 29 | { 30 | IniFile.SetStringValue(IniSection, IniKey, string.Join(",", Get())); 31 | } 32 | 33 | public void Add(string value) 34 | { 35 | var values = Get().Concat(new[] { value }).ToList(); 36 | Set(values); 37 | } 38 | 39 | public void Remove(string value) 40 | { 41 | var values = Get().Where(v => !string.Equals(v, value, StringComparison.InvariantCultureIgnoreCase)).ToList(); 42 | Set(values); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ClientCore/Settings/StringSetting.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | 3 | namespace ClientCore.Settings 4 | { 5 | public class StringSetting : INISetting 6 | { 7 | public StringSetting(IniFile iniFile, string iniSection, string iniKey, string defaultValue) 8 | : base(iniFile, iniSection, iniKey, defaultValue) 9 | { 10 | } 11 | 12 | protected override string Get() 13 | { 14 | return IniFile.GetStringValue(IniSection, IniKey, DefaultValue); 15 | } 16 | 17 | protected override void Set(string value) 18 | { 19 | IniFile.SetStringValue(IniSection, IniKey, value); 20 | } 21 | 22 | public override void Write() 23 | { 24 | IniFile.SetStringValue(IniSection, IniKey, Get()); 25 | } 26 | 27 | public override string ToString() 28 | { 29 | return Get(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ClientCore/Statistics/DataWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace ClientCore.Statistics 6 | { 7 | internal static class DataWriter 8 | { 9 | public static void WriteInt(this Stream stream, int value) 10 | { 11 | stream.Write(BitConverter.GetBytes(value), 0, sizeof(int)); 12 | } 13 | 14 | public static void WriteLong(this Stream stream, long value) 15 | { 16 | stream.Write(BitConverter.GetBytes(value), 0, sizeof(long)); 17 | } 18 | 19 | public static void WriteBool(this Stream stream, bool value) 20 | { 21 | stream.WriteByte(Convert.ToByte(value)); 22 | } 23 | 24 | public static void WriteString(this Stream stream, string value, int reservedSpace, Encoding encoding = null) 25 | { 26 | if (encoding == null) 27 | encoding = Encoding.Unicode; 28 | 29 | byte[] writeBuffer = encoding.GetBytes(value); 30 | if (writeBuffer.Length != reservedSpace) 31 | { 32 | // If the name's byte presentation is not equal to reservedSpace, 33 | // let's resize the array 34 | byte[] temp = writeBuffer; 35 | writeBuffer = new byte[reservedSpace]; 36 | for (int j = 0; j < temp.Length && j < writeBuffer.Length; j++) 37 | writeBuffer[j] = temp[j]; 38 | } 39 | 40 | stream.Write(writeBuffer, 0, writeBuffer.Length); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ClientCore/Statistics/GenericMatchParser.cs: -------------------------------------------------------------------------------- 1 | namespace ClientCore.Statistics 2 | { 3 | public abstract class GenericMatchParser 4 | { 5 | public MatchStatistics Statistics { get; set; } 6 | 7 | public GenericMatchParser(MatchStatistics ms) 8 | { 9 | Statistics = ms; 10 | } 11 | 12 | protected abstract void ParseStatistics(string gamepath); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ClientCore/Statistics/GenericStatisticsManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace ClientCore.Statistics 6 | { 7 | public abstract class GenericStatisticsManager 8 | { 9 | protected List Statistics = new List(); 10 | 11 | protected static string GetStatDatabaseVersion(string scorePath) 12 | { 13 | if (!File.Exists(scorePath)) 14 | { 15 | return null; 16 | } 17 | 18 | using (StreamReader reader = new StreamReader(scorePath)) 19 | { 20 | char[] versionBuffer = new char[4]; 21 | reader.Read(versionBuffer, 0, versionBuffer.Length); 22 | 23 | String s = new String(versionBuffer); 24 | 25 | return s; 26 | 27 | } 28 | } 29 | 30 | public abstract void ReadStatistics(string gamePath); 31 | 32 | public int GetMatchCount() { return Statistics.Count; } 33 | 34 | public MatchStatistics GetMatchByIndex(int index) 35 | { 36 | return Statistics[index]; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ClientGUI/CDebugView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Runtime.InteropServices; 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace ClientGUI 7 | { 8 | /// 9 | /// 监控异常跟踪类,可在调试/发布版本下实时打印日志信息 10 | /// 11 | public class CDebugView 12 | { 13 | [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 14 | private static extern void OutputDebugString(string message); 15 | 16 | private static string _strPrefix = string.Empty; 17 | 18 | public static void SetDebugName(string strName) 19 | { 20 | if (string.IsNullOrEmpty(strName)) 21 | _strPrefix = "[ClientGUI]"; 22 | else 23 | _strPrefix = string.Format("[{0}]", strName); 24 | } 25 | 26 | public static void OutputDebugInfo(string strMsg) 27 | { 28 | StringBuilder sBuff = new StringBuilder(); 29 | sBuff.AppendFormat("{0}{1}", _strPrefix, strMsg); 30 | OutputDebugString(sBuff.ToString()); 31 | Console.WriteLine(sBuff.ToString()); 32 | sBuff.Clear(); 33 | } 34 | 35 | public static void OutputDebugInfo(string strMsg, params object[] arg) 36 | { 37 | StringBuilder sBuff = new StringBuilder(); 38 | sBuff.AppendFormat(strMsg, arg); 39 | OutputDebugInfo(sBuff.ToString()); 40 | sBuff.Clear(); 41 | } 42 | 43 | public static void TraceMessage(string strMsg, 44 | [CallerMemberName] string memberName = null, 45 | [CallerFilePath] string sourceFilePath = null, 46 | [CallerLineNumber] int sourceLineNumber = default(int)) 47 | { 48 | StringBuilder sBuff = new StringBuilder(); 49 | sBuff.AppendFormat("{0}{1}-{2}:{3}:{4}", _strPrefix, sourceFilePath, memberName, sourceLineNumber, strMsg); 50 | System.Diagnostics.Debug.WriteLine(sBuff); 51 | sBuff.Clear(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ClientGUI/ClientGUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0-windows7.0 4 | 13.0 5 | Client GUI 6 | Client GUI Library 7 | Snowy 8 | Client GUI 9 | Copyright © Snowy Studio 2022-2025 10 | Snowy 11 | 1.0.0.0 12 | 1.0.0.0 13 | 1.0.0.0 14 | ClientGUI 15 | ClientGUI 16 | disable 17 | false 18 | 19 | 20 | $(DefineConstants); 21 | ..\Bin\Resources\Binaries 22 | 23 | 24 | $(DefineConstants); 25 | ..\Bin\Resources\Binaries 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ClientGUI/IME/DummyIMEHandler.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | using Microsoft.Xna.Framework; 3 | 4 | namespace ClientGUI.IME 5 | { 6 | internal class DummyIMEHandler : IMEHandler 7 | { 8 | public DummyIMEHandler() { } 9 | 10 | public override bool TextCompositionEnabled { get => false; protected set { } } 11 | 12 | public override void SetTextInputRectangle(Rectangle rectangle) { } 13 | public override void StartTextComposition() { } 14 | public override void StopTextComposition() { } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ClientGUI/IME/SdlIMEHandler.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | using Microsoft.Xna.Framework; 3 | 4 | namespace ClientGUI.IME; 5 | 6 | /// 7 | /// Integrate IME to DesktopGL(SDL2) platform. 8 | /// 9 | /// 10 | /// Note: We were unable to provide reliable input method support for 11 | /// SDL2 due to the lack of a way to be able to stabilize hooks for 12 | /// the SDL2 main loop.
13 | /// Perhaps this requires some changes in Monogame. 14 | ///
15 | internal sealed class SdlIMEHandler(Game game) : DummyIMEHandler 16 | { 17 | } -------------------------------------------------------------------------------- /ClientGUI/IME/WinFormsIMEHandler.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | using System; 3 | 4 | using ImeSharp; 5 | 6 | using Microsoft.Xna.Framework; 7 | 8 | using Rampastring.Tools; 9 | 10 | namespace ClientGUI.IME; 11 | 12 | /// 13 | /// Integrate IME to XNA framework. 14 | /// 15 | internal class WinFormsIMEHandler : IMEHandler 16 | { 17 | public override bool TextCompositionEnabled 18 | { 19 | get => InputMethod.Enabled; 20 | protected set 21 | { 22 | if (value != InputMethod.Enabled) 23 | InputMethod.Enabled = value; 24 | } 25 | } 26 | 27 | public WinFormsIMEHandler(Game game) 28 | { 29 | Logger.Log($"Initialize WinFormsIMEHandler."); 30 | if (game?.Window?.Handle == null) 31 | throw new Exception("The handle of game window should not be null"); 32 | 33 | InputMethod.Initialize(game.Window.Handle); 34 | InputMethod.TextInputCallback = OnIMETextInput; 35 | InputMethod.TextCompositionCallback = (compositionText, cursorPosition) => 36 | { 37 | Composition = compositionText.ToString(); 38 | CompositionCursorPosition = cursorPosition; 39 | }; 40 | } 41 | 42 | public override void StartTextComposition() 43 | { 44 | //Debug.WriteLine("IME: StartTextComposition"); 45 | TextCompositionEnabled = true; 46 | } 47 | 48 | public override void StopTextComposition() 49 | { 50 | //Debug.WriteLine("IME: StopTextComposition"); 51 | TextCompositionEnabled = false; 52 | } 53 | 54 | public override void SetTextInputRectangle(Rectangle rect) 55 | => InputMethod.SetTextInputRect(rect.X, rect.Y, rect.Width, rect.Height); 56 | } 57 | -------------------------------------------------------------------------------- /ClientGUI/INIConfigException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClientGUI 4 | { 5 | /// 6 | /// The exception that is thrown when INI data is invalid. 7 | /// 8 | public class INIConfigException : Exception 9 | { 10 | public INIConfigException(string message) : base(message) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ClientGUI/UIDesignConstants.cs: -------------------------------------------------------------------------------- 1 | namespace ClientGUI 2 | { 3 | /// 4 | /// Contains constants used in user interface design. 5 | /// 6 | public static class UIDesignConstants 7 | { 8 | public const int EMPTY_SPACE_SIDES = 6; 9 | public const int EMPTY_SPACE_TOP = 6; 10 | public const int EMPTY_SPACE_BOTTOM = 6; 11 | 12 | public const int CONTROL_VERTICAL_MARGIN = 6; 13 | public const int CONTROL_HORIZONTAL_MARGIN = 6; 14 | 15 | public const int BUTTON_HEIGHT = 23; 16 | public const int BUTTON_WIDTH_75 = 75; 17 | public const int BUTTON_WIDTH_92 = 92; 18 | public const int BUTTON_WIDTH_121 = 121; 19 | public const int BUTTON_WIDTH_133 = 133; 20 | public const int BUTTON_WIDTH_160 = 160; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ClientGUI/WindowControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace ClientGUI 5 | { 6 | public class WindowControl 7 | { 8 | [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] 9 | private static extern IntPtr FindWindow(string lpszClass, string lpszWindow); 10 | 11 | [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)] 12 | private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 13 | 14 | [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] 15 | private static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow); 16 | 17 | private static IntPtr _wndHandle = IntPtr.Zero; 18 | 19 | public static IntPtr WindowHandle { get => _wndHandle; set => _wndHandle = value; } 20 | 21 | public static bool DisplayWindow(uint nShow = 0) 22 | { 23 | if(IntPtr.Zero == _wndHandle) 24 | return false; 25 | ShowWindow(_wndHandle, nShow); 26 | return true; 27 | } 28 | 29 | public static IntPtr? FindWindow(string strName) 30 | { 31 | return FindWindow(null, strName); 32 | } 33 | 34 | public static bool DisplayWindow(IntPtr handle, uint nShow = 0) 35 | { 36 | if (IntPtr.Zero == handle) 37 | return false; 38 | ShowWindow(handle, nShow); 39 | return true; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ClientGUI/XNAChatTextBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Xna.Framework.Input; 4 | using Rampastring.XNAUI; 5 | using Rampastring.XNAUI.XNAControls; 6 | 7 | namespace ClientGUI 8 | { 9 | /// 10 | /// A text box that stores entered messages and allows viewing them 11 | /// with the arrow keys. 12 | /// 13 | public class XNAChatTextBox : XNASuggestionTextBox 14 | { 15 | public XNAChatTextBox(WindowManager windowManager) : base(windowManager) 16 | { 17 | EnterPressed += XNAChatTextBox_EnterPressed; 18 | } 19 | 20 | private LinkedList enteredMessages = new LinkedList(); 21 | private LinkedListNode currentNode; 22 | 23 | 24 | 25 | private void XNAChatTextBox_EnterPressed(object sender, EventArgs e) 26 | { 27 | if (!string.IsNullOrEmpty(Text)) 28 | enteredMessages.AddFirst(Text); 29 | } 30 | 31 | protected override bool HandleKeyPress(Keys key) 32 | { 33 | if (key == Keys.Up) 34 | { 35 | if (currentNode == null) 36 | { 37 | if (enteredMessages.First != null) 38 | currentNode = enteredMessages.First; 39 | } 40 | else 41 | { 42 | if (currentNode.Next != null) 43 | currentNode = currentNode.Next; 44 | } 45 | 46 | if (currentNode != null) 47 | Text = currentNode.Value; 48 | 49 | return true; 50 | } 51 | 52 | if (key == Keys.Down) 53 | { 54 | if (currentNode != null && currentNode.Previous != null) 55 | { 56 | currentNode = currentNode.Previous; 57 | Text = currentNode.Value; 58 | } 59 | 60 | return true; 61 | } 62 | 63 | currentNode = null; 64 | return base.HandleKeyPress(key); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ClientGUI/XNAClientButton.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | using Rampastring.XNAUI; 3 | using Rampastring.XNAUI.XNAControls; 4 | using System; 5 | 6 | namespace ClientGUI 7 | { 8 | public class XNAClientButton : XNAButton 9 | { 10 | private string _toolTipText { get; set; } 11 | 12 | private ToolTip _toolTip { get; set; } 13 | 14 | public XNAClientButton(WindowManager windowManager) : base(windowManager) 15 | { 16 | FontIndex = 1; 17 | 18 | Width = UIDesignConstants.BUTTON_WIDTH_160; 19 | Height = UIDesignConstants.BUTTON_HEIGHT; 20 | 21 | } 22 | 23 | 24 | 25 | public override void Initialize() 26 | { 27 | int width = Width; 28 | 29 | if (IdleTexture == null) 30 | IdleTexture = AssetLoader.LoadTexture(width + "pxbtn.png"); 31 | 32 | if (HoverTexture == null) 33 | HoverTexture = AssetLoader.LoadTexture(width + "pxbtn_c.png"); 34 | 35 | if (HoverSoundEffect == null) 36 | HoverSoundEffect = new EnhancedSoundEffect("button.wav"); 37 | 38 | base.Initialize(); 39 | 40 | if (Width == 0) 41 | Width = IdleTexture.Width; 42 | 43 | _toolTip = new ToolTip(WindowManager, this); 44 | SetToolTipText(_toolTipText); 45 | } 46 | 47 | public override void ParseControlINIAttribute(IniFile iniFile, string key, string value) 48 | { 49 | if (key == "MatchTextureSize" && Conversions.BooleanFromString(value, false)) 50 | { 51 | Width = IdleTexture.Width; 52 | Height = IdleTexture.Height; 53 | return; 54 | } 55 | 56 | base.ParseControlINIAttribute(iniFile, key, value); 57 | } 58 | 59 | public void SetToolTipText(string text) 60 | { 61 | _toolTipText = text ?? string.Empty; 62 | if (_toolTip != null) 63 | _toolTip.Text = _toolTipText; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ClientGUI/XNAClientCheckBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Localization; 3 | using Rampastring.Tools; 4 | using Rampastring.XNAUI; 5 | using Rampastring.XNAUI.XNAControls; 6 | 7 | namespace ClientGUI 8 | { 9 | public class XNAClientCheckBox : XNACheckBox 10 | { 11 | private ToolTip ToolTip { get; set; } 12 | private string _toolTipText { get; set; } 13 | 14 | public XNAClientCheckBox(WindowManager windowManager) : base(windowManager) 15 | { 16 | } 17 | 18 | private void CreateToolTip() 19 | { 20 | ToolTip ??= new ToolTip(WindowManager, this); 21 | } 22 | 23 | public override void Initialize() 24 | { 25 | CheckSoundEffect = new EnhancedSoundEffect("checkbox.wav"); 26 | 27 | base.Initialize(); 28 | 29 | CreateToolTip(); 30 | SetToolTipText(_toolTipText); 31 | } 32 | 33 | public void SetToolTipText(string text) 34 | { 35 | _toolTipText = text ?? string.Empty; 36 | if (ToolTip != null) 37 | ToolTip.Text = _toolTipText; 38 | } 39 | 40 | public override void ParseControlINIAttribute(IniFile iniFile, string key, string value) 41 | { 42 | if (key == "ToolTip") 43 | { 44 | CreateToolTip(); 45 | SetToolTipText(value.Replace("@", Environment.NewLine)); 46 | return; 47 | } 48 | if (key == "$ToolTip") 49 | { 50 | CreateToolTip(); 51 | SetToolTipText(value.Replace("@", Environment.NewLine)); 52 | return; 53 | } 54 | base.ParseControlINIAttribute(iniFile, key, value); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ClientGUI/XNAClientRatingBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Localization; 3 | using Rampastring.Tools; 4 | using Rampastring.XNAUI; 5 | using Rampastring.XNAUI.XNAControls; 6 | 7 | namespace ClientGUI 8 | { 9 | public class XNAClientRatingBox : XNARatingBox 10 | { 11 | public ToolTip ToolTip { get; set; } 12 | 13 | public XNAClientRatingBox(WindowManager windowManager) : base(windowManager) 14 | { 15 | } 16 | 17 | private void CreateToolTip() 18 | { 19 | if (ToolTip == null) 20 | ToolTip = new ToolTip(WindowManager, this); 21 | } 22 | 23 | public override void Initialize() 24 | { 25 | CheckSoundEffect = new EnhancedSoundEffect("checkbox.wav"); 26 | 27 | base.Initialize(); 28 | 29 | CreateToolTip(); 30 | } 31 | 32 | public override void ParseControlINIAttribute(IniFile iniFile, string key, string value) 33 | { 34 | if (key == "ToolTip") 35 | { 36 | CreateToolTip(); 37 | ToolTip.Text = value.Replace("@", Environment.NewLine); 38 | return; 39 | } 40 | if (key == "$ToolTip") 41 | { 42 | CreateToolTip(); 43 | ToolTip.Text = string.Empty.L10N("UI:Main:" + value).Replace("@", Environment.NewLine); 44 | return; 45 | } 46 | base.ParseControlINIAttribute(iniFile, key, value); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ClientGUI/XNAClientTabControl.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.XNAUI; 2 | using Rampastring.XNAUI.XNAControls; 3 | 4 | namespace ClientGUI 5 | { 6 | public class XNAClientTabControl : XNATabControl 7 | { 8 | public XNAClientTabControl(WindowManager windowManager) : base(windowManager) 9 | { 10 | } 11 | 12 | public override void Initialize() 13 | { 14 | if (ClickSound == null) 15 | { 16 | ClickSound = new EnhancedSoundEffect("button.wav"); 17 | } 18 | 19 | 20 | base.Initialize(); 21 | } 22 | 23 | public XNAClientTabControl AddTab(string text, int width) 24 | { 25 | string tabAssetName = width + "pxtab"; 26 | 27 | if (AssetLoader.AssetExists(tabAssetName + ".png")) 28 | { 29 | AddTab(text, AssetLoader.LoadTexture(tabAssetName + ".png"), 30 | AssetLoader.LoadTexture(tabAssetName + "_c.png")); 31 | } 32 | else 33 | { 34 | AddTab(text, AssetLoader.LoadTexture(width + "pxbtn.png"), 35 | AssetLoader.LoadTexture(width + "pxbtn_c.png")); 36 | } 37 | return this; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ClientGUI/XNAExtraPanel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Rampastring.Tools; 3 | using Rampastring.XNAUI; 4 | using Rampastring.XNAUI.XNAControls; 5 | 6 | namespace ClientGUI 7 | { 8 | /// 9 | /// An "extra panel" for modders that automatically 10 | /// changes its size to match the texture size. 11 | /// 12 | public class XNAExtraPanel : XNAPanel 13 | { 14 | public XNAExtraPanel(WindowManager windowManager) : base(windowManager) 15 | { 16 | InputEnabled = false; 17 | DrawBorders = false; 18 | } 19 | 20 | public override void ParseControlINIAttribute(IniFile iniFile, string key, string value) 21 | { 22 | if (key == "BackgroundTexture") 23 | { 24 | BackgroundTexture = AssetLoader.LoadTexture(value); 25 | 26 | if (new Point(Width, Height) == Point.Zero) 27 | { 28 | ClientRectangle = new Rectangle(X, Y, 29 | BackgroundTexture.Width, BackgroundTexture.Height); 30 | } 31 | 32 | return; 33 | } 34 | 35 | base.ParseControlINIAttribute(iniFile, key, value); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ClientGUI/XNALinkButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ClientCore; 3 | using Rampastring.Tools; 4 | using Rampastring.XNAUI; 5 | 6 | namespace ClientGUI 7 | { 8 | public class XNALinkButton : XNAClientButton 9 | { 10 | public XNALinkButton(WindowManager windowManager) : base(windowManager) 11 | { 12 | } 13 | 14 | public string URL { get; set; } 15 | 16 | private ToolTip toolTip; 17 | 18 | private void CreateToolTip() 19 | { 20 | if (toolTip == null) 21 | toolTip = new ToolTip(WindowManager, this); 22 | } 23 | 24 | public override void Initialize() 25 | { 26 | base.Initialize(); 27 | 28 | CreateToolTip(); 29 | } 30 | 31 | public override void ParseControlINIAttribute(IniFile iniFile, string key, string value) 32 | { 33 | if (key == "URL") 34 | { 35 | URL = value; 36 | return; 37 | } 38 | else if (key == "ToolTip") 39 | { 40 | CreateToolTip(); 41 | toolTip.Text = value.Replace("@", Environment.NewLine); 42 | return; 43 | } 44 | 45 | base.ParseControlINIAttribute(iniFile, key, value); 46 | } 47 | 48 | public override void OnLeftClick() 49 | { 50 | if(URL!=null) 51 | ProcessLauncher.StartShellProcess(URL); 52 | 53 | base.OnLeftClick(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /ClientGUI/XNAWindowSingleton.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.XNAUI; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace ClientGUI 9 | { 10 | public class XNAWindowSingleton(WindowManager windowManager) : XNAWindow(windowManager) 11 | { 12 | private static XNAWindowSingleton Instance = null; 13 | 14 | public static XNAWindowSingleton GetInstance(WindowManager windowManager) 15 | { 16 | Instance ??= new XNAWindowSingleton(windowManager); 17 | return Instance; 18 | } 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ClientUpdater/ClientUpdater.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0-windows7.0 4 | 13.0 5 | Exe 6 | 7 | Ra2Client Updater 8 | 9 | 10 | Copyright © Snowy Studio 2022-2025 11 | Snowy 12 | ClientUpdater 13 | ClientUpdater 14 | disable 15 | false 16 | false 17 | latest-all 18 | true 19 | AnyCPU 20 | false 21 | false 22 | false 23 | false 24 | False 25 | 1.5.0.0 26 | 1.5.0.0 27 | app.manifest 28 | 29 | 30 | 1701;1702;SA1633; 31 | ..\Bin\Resources\Binaries 32 | 33 | 34 | 1701;1702;SA1633; 35 | ..\Bin\Resources\Binaries 36 | 37 | 38 | 39 | all 40 | runtime; build; native; contentfiles; analyzers; buildtransitive 41 | 42 | 43 | -------------------------------------------------------------------------------- /ClientUpdater/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "ClientUpdater": { 4 | "commandName": "Project", 5 | "commandLineArgs": "Ra2Client.dll \"E:\\Documents\\file\\RF-Client\\Bin\\\"" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /DTAConfig/DTAConfig.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | UI -------------------------------------------------------------------------------- /DTAConfig/OptionPanels/DisplayOptionsPanel.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/DTAConfig/OptionPanels/DisplayOptionsPanel.cs -------------------------------------------------------------------------------- /DTAConfig/Settings/ColorSpace.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework; 3 | 4 | namespace DTAConfig.Settings 5 | { 6 | public class ColorSpace 7 | { 8 | public static Color RGB2HSI(Color rgb) 9 | { 10 | double h, s, i; 11 | double r = rgb.R / 255.0; 12 | double g = rgb.G / 255.0; 13 | double b = rgb.B / 255.0; 14 | 15 | double theta = Math.Acos(0.5 * ((r - g) + (r - b))/Math.Sqrt((r - g) * (r - g) + (r - b) * (g - b))) / (2 * Math.PI); 16 | 17 | h = (b <= g) ? theta : (1 - theta); 18 | s = (1 - 3 * Math.Min(Math.Min(r, g), b) / (r + g + b)); 19 | i = (r + g + b) / 3.0; 20 | return new Color((byte)(h * 255.0 + .5), (byte)(s * 255.0 + .5), (byte)(i * 255.0 + .5)); 21 | } 22 | 23 | public static Color HSI2RGB(Color hsi) 24 | { 25 | double r, g, b; 26 | 27 | double h = hsi.R; 28 | double s = hsi.G; 29 | double i = hsi.B; 30 | 31 | h = h * 2 * Math.PI; 32 | if(h > 0 && h < (2 *Math.PI / 3)) 33 | { 34 | b = i * (1 - s); 35 | r = i * (1 + s * Math.Cos(h) / Math.Cos(Math.PI / 3 - h)); 36 | g = 3 * i - (r + b); 37 | } 38 | else if( h >= 2 * Math.PI / 3 && h < 4 * Math.PI/ 3) 39 | { 40 | r = i * (1 - s); 41 | g = i * (1 + s * Math.Cos(h - 2 * Math.PI / 3) / Math.Cos(Math.PI - h)); 42 | b = 3 * i - (r + g); 43 | } 44 | else 45 | { 46 | g = i * (1 - s); 47 | b = i * (1 + s * Math.Cos(h - 4 * Math.PI / 3) / Math.Cos(5 * Math.PI / 3 - h)); 48 | r = 3 * i - (g + b); 49 | } 50 | 51 | return new Color((byte)(r * 255.0 + .5), (byte)(g * 255.0 + .5), (byte)(b * 255.0 + .5)); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /DTAConfig/Settings/IFileSetting.cs: -------------------------------------------------------------------------------- 1 | namespace DTAConfig.Settings 2 | { 3 | interface IFileSetting : IUserSetting 4 | { 5 | /// 6 | /// Determines if the setting availability is checked on runtime. 7 | /// 8 | bool CheckAvailability { get; } 9 | 10 | /// 11 | /// Determines if the client would adjust the setting value automatically 12 | /// if the current value becomes unavailable. 13 | /// 14 | bool ResetUnavailableValue { get; } 15 | 16 | /// 17 | /// Refreshes the setting to account for possible 18 | /// changes that could affect it's functionality. 19 | /// 20 | /// A bool that determines whether the 21 | /// setting's value was changed. 22 | bool RefreshSetting(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DTAConfig/Settings/IUserSetting.cs: -------------------------------------------------------------------------------- 1 | namespace DTAConfig.Settings 2 | { 3 | interface IUserSetting 4 | { 5 | 6 | /// 7 | /// INI Section name in user settings file this setting's value is stored in. 8 | /// 9 | string SettingSection { get; } 10 | 11 | /// 12 | /// INI key name in user settings file this setting's value is stored in. 13 | /// 14 | string SettingKey { get; } 15 | 16 | /// 17 | /// Determines if this setting requires the client to be restarted 18 | /// in order to be correctly applied. 19 | /// 20 | bool RestartRequired { get; } 21 | 22 | /// 23 | /// Loads the current value for the user setting. 24 | /// 25 | void Load(); 26 | 27 | /// 28 | /// Applies operations based on current setting state. 29 | /// 30 | /// A bool that determines whether the 31 | /// client needs to restart for changes to apply. 32 | bool Save(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Localization/ExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Localization 4 | { 5 | public static class StringTranslationLabelExtensions 6 | { 7 | /// 8 | /// Mark this string to be translated, with the given label name. 9 | /// 10 | /// The default string value as a fallback. 11 | /// The unique label name. 12 | /// The translated string value. 13 | public static string L10N(this String defaultValue, string label) 14 | => TranslationTable.Instance.GetTableValue(label, defaultValue); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Localization/Localization.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0-windows7.0 4 | latest 5 | Localization 6 | Localization Library 7 | Snowy 8 | Localization 9 | Copyright © Snowy Studio 2022-2025 10 | Snowy 11 | 1.0.0.0 12 | 1.0.0.0 13 | 1.0.0.0 14 | Localization 15 | Localization 16 | disable 17 | false 18 | False 19 | 20 | 21 | 1701;1702;CA1416; 22 | ..\Bin\Resources\Binaries 23 | 24 | 25 | 1701;1702;CA1416; 26 | ..\Bin\Resources\Binaries 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Localization/MissingTranslationEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Localization 4 | { 5 | public class MissingTranslationEventArgs : EventArgs 6 | { 7 | public string LanguageTag { get; set; } 8 | public string Label { get; set; } 9 | public string DefaultValue { get; set; } 10 | 11 | public MissingTranslationEventArgs(string languageTag, string label, string defaultValue) 12 | { 13 | LanguageTag = languageTag; 14 | Label = label; 15 | DefaultValue = defaultValue; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Localization/SevenZip/ArchiveFileCallback.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Localization.SevenZip 5 | { 6 | internal class ArchiveFileCallback : IArchiveExtractCallback 7 | { 8 | private readonly string fileName; 9 | private readonly uint fileNumber; 10 | private OutStreamWrapper fileStream; // to be removed 11 | 12 | public ArchiveFileCallback(uint fileNumber, string fileName) 13 | { 14 | this.fileNumber = fileNumber; 15 | this.fileName = fileName; 16 | } 17 | 18 | public void SetTotal(ulong total) 19 | { 20 | } 21 | 22 | public void SetCompleted(ref ulong completeValue) 23 | { 24 | } 25 | 26 | public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 27 | { 28 | if ((index != this.fileNumber) || (askExtractMode != AskMode.kExtract)) 29 | { 30 | outStream = null; 31 | return 0; 32 | } 33 | 34 | string fileDir = Path.GetDirectoryName(this.fileName); 35 | 36 | if (!string.IsNullOrEmpty(fileDir)) 37 | { 38 | Directory.CreateDirectory(fileDir); 39 | } 40 | 41 | this.fileStream = new OutStreamWrapper(File.Create(this.fileName)); 42 | 43 | outStream = this.fileStream; 44 | 45 | return 0; 46 | } 47 | 48 | public void PrepareOperation(AskMode askExtractMode) 49 | { 50 | } 51 | 52 | public void SetOperationResult(OperationResult resultEOperationResult) 53 | { 54 | this.fileStream.Dispose(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Localization/SevenZip/ArchiveStreamCallback.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Localization.SevenZip 4 | { 5 | internal class ArchiveStreamCallback : IArchiveExtractCallback 6 | { 7 | private readonly uint fileNumber; 8 | private readonly Stream stream; 9 | 10 | public ArchiveStreamCallback(uint fileNumber, Stream stream) 11 | { 12 | this.fileNumber = fileNumber; 13 | this.stream = stream; 14 | } 15 | 16 | public void SetTotal(ulong total) 17 | { 18 | } 19 | 20 | public void SetCompleted(ref ulong completeValue) 21 | { 22 | } 23 | 24 | public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 25 | { 26 | if ((index != this.fileNumber) || (askExtractMode != AskMode.kExtract)) 27 | { 28 | outStream = null; 29 | return 0; 30 | } 31 | 32 | outStream = new OutStreamWrapper(this.stream); 33 | 34 | return 0; 35 | } 36 | 37 | public void PrepareOperation(AskMode askExtractMode) 38 | { 39 | } 40 | 41 | public void SetOperationResult(OperationResult resultEOperationResult) 42 | { 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Localization/SevenZip/ArchiveStreamsCallback.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace Localization.SevenZip 5 | { 6 | internal class ArchiveStreamsCallback : IArchiveExtractCallback 7 | { 8 | private readonly IList streams; 9 | 10 | public ArchiveStreamsCallback(IList streams) 11 | { 12 | this.streams = streams; 13 | } 14 | 15 | public void SetTotal(ulong total) 16 | { 17 | } 18 | 19 | public void SetCompleted(ref ulong completeValue) 20 | { 21 | } 22 | 23 | public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 24 | { 25 | if (askExtractMode != AskMode.kExtract) 26 | { 27 | outStream = null; 28 | return 0; 29 | } 30 | 31 | if (this.streams == null) 32 | { 33 | outStream = null; 34 | return 0; 35 | } 36 | 37 | Stream stream = this.streams[(int) index]; 38 | 39 | if (stream == null) 40 | { 41 | outStream = null; 42 | return 0; 43 | } 44 | 45 | outStream = new OutStreamWrapper(stream); 46 | 47 | return 0; 48 | } 49 | 50 | public void PrepareOperation(AskMode askExtractMode) 51 | { 52 | } 53 | 54 | public void SetOperationResult(OperationResult resultEOperationResult) 55 | { 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /Localization/SevenZip/IArchiveExtractCallback.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace Localization.SevenZip 4 | { 5 | [ComImport] 6 | [Guid("23170F69-40C1-278A-0000-000600200000")] 7 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 8 | internal interface IArchiveExtractCallback //: IProgress 9 | { 10 | void SetTotal(ulong total); 11 | void SetCompleted([In] ref ulong completeValue); 12 | 13 | [PreserveSig] 14 | int GetStream( 15 | uint index, 16 | [MarshalAs(UnmanagedType.Interface)] out ISequentialOutStream outStream, 17 | AskMode askExtractMode); 18 | // GetStream OUT: S_OK - OK, S_FALSE - skeep this file 19 | 20 | void PrepareOperation(AskMode askExtractMode); 21 | void SetOperationResult(OperationResult resultEOperationResult); 22 | } 23 | } -------------------------------------------------------------------------------- /Localization/SevenZip/Kernel32Dll.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Security; 4 | 5 | namespace Localization.SevenZip 6 | { 7 | internal static class Kernel32Dll 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | internal static extern SafeLibraryHandle LoadLibrary([MarshalAs(UnmanagedType.LPTStr)] string lpFileName); 11 | 12 | [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] 13 | internal static extern IntPtr GetProcAddress(SafeLibraryHandle hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); 14 | 15 | [SuppressUnmanagedCodeSecurity] 16 | [DllImport("kernel32.dll")] 17 | [return: MarshalAs(UnmanagedType.Bool)] 18 | internal static extern bool FreeLibrary(IntPtr hModule); 19 | } 20 | } -------------------------------------------------------------------------------- /Localization/SevenZip/SafeLibraryHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.ConstrainedExecution; 3 | using Microsoft.Win32.SafeHandles; 4 | 5 | namespace Localization.SevenZip 6 | { 7 | internal sealed class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid 8 | { 9 | public SafeLibraryHandle() : base(true) 10 | { 11 | } 12 | 13 | /// Release library handle 14 | /// true if the handle was released 15 | protected override bool ReleaseHandle() => Kernel32Dll.FreeLibrary(this.handle); 16 | } 17 | } -------------------------------------------------------------------------------- /Localization/SevenZip/SevenZipException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Localization.SevenZip 5 | { 6 | public class SevenZipException : Exception 7 | { 8 | public SevenZipException() 9 | { 10 | } 11 | 12 | public SevenZipException(string message) : base(message) 13 | { 14 | } 15 | 16 | public SevenZipException(string message, Exception innerException) : base(message, innerException) 17 | { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /RA2Client/DXGUI/Generic/GameLoadingWindow.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/DXGUI/Generic/GameLoadingWindow.cs -------------------------------------------------------------------------------- /RA2Client/DXGUI/Generic/VideoRenderer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Rampastring.XNAUI; 4 | 5 | namespace Ra2Client.DXGUI.Generic 6 | { 7 | public class VideoRenderer : DrawableGameComponent 8 | { 9 | public VideoRenderer(WindowManager windowManager, GraphicsDevice graphicsDevice) : base(windowManager.Game) 10 | { 11 | this.windowManager = windowManager; 12 | this.graphicsDevice = graphicsDevice; 13 | spriteBatch = new SpriteBatch(graphicsDevice); 14 | } 15 | 16 | private WindowManager windowManager; 17 | private GraphicsDevice graphicsDevice; 18 | private SpriteBatch spriteBatch; 19 | 20 | public Texture2D VideoTexture { get; set; } 21 | 22 | public override void Draw(GameTime gameTime) 23 | { 24 | if (VideoTexture != null) 25 | { 26 | spriteBatch.Begin(); 27 | spriteBatch.Draw(VideoTexture, new Rectangle(0, 0, 1280, 768), Color.White); 28 | spriteBatch.End(); 29 | } 30 | 31 | base.Draw(gameTime); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/IMessageView.cs: -------------------------------------------------------------------------------- 1 | using Ra2Client.Online; 2 | 3 | namespace Ra2Client.DXGUI 4 | { 5 | public interface IMessageView 6 | { 7 | void AddMessage(ChatMessage message); 8 | } 9 | } -------------------------------------------------------------------------------- /RA2Client/DXGUI/ISwitchable.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.DXGUI 2 | { 3 | /// 4 | /// An interface for all switchable windows. 5 | /// 6 | public interface ISwitchable 7 | { 8 | void SwitchOn(); 9 | 10 | void SwitchOff(); 11 | 12 | string GetSwitchName(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/CnCNet/GameCreationEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Ra2Client.Domain.Multiplayer.CnCNet; 3 | 4 | namespace Ra2Client.DXGUI.Multiplayer.CnCNet 5 | { 6 | class GameCreationEventArgs : EventArgs 7 | { 8 | public GameCreationEventArgs(string roomName, int maxPlayers, 9 | string password, CnCNetTunnel tunnel, int skillLevel) 10 | { 11 | GameRoomName = roomName; 12 | MaxPlayers = maxPlayers; 13 | Password = password; 14 | Tunnel = tunnel; 15 | SkillLevel = skillLevel; 16 | } 17 | 18 | public string GameRoomName { get; private set; } 19 | public int MaxPlayers { get; private set; } 20 | public string Password { get; private set; } 21 | public CnCNetTunnel Tunnel { get; private set; } 22 | public int SkillLevel { get; private set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/CnCNet/GlobalContextMenuData.cs: -------------------------------------------------------------------------------- 1 | using Ra2Client.Online; 2 | 3 | namespace Ra2Client.DXGUI.Multiplayer.CnCNet 4 | { 5 | public class GlobalContextMenuData 6 | { 7 | /// 8 | /// The ChannelUser to show the menu for. 9 | /// 10 | public ChannelUser ChannelUser { get; set; } 11 | 12 | /// 13 | /// The ChatMessage to show the menu for. 14 | /// 15 | public ChatMessage ChatMessage { get; set; } 16 | 17 | /// 18 | /// The IRCUser to show the menu for. 19 | /// 20 | public IRCUser IrcUser { get; set; } 21 | 22 | /// 23 | /// The player to show the menu for. This is used to determine the IRCUser internally. 24 | /// 25 | public string PlayerName { get; set; } 26 | 27 | /// 28 | /// The invite properties are used for the Invite option in the menu. 29 | /// 30 | public string inviteChannelName { get; set; } 31 | public string inviteGameName { get; set; } 32 | public string inviteChannelPassword { get; set; } 33 | 34 | /// 35 | /// Prevent the Join option from showing in the menu. 36 | /// 37 | public bool PreventJoinGame { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/CnCNet/PrivateMessagingPanel.cs: -------------------------------------------------------------------------------- 1 | using ClientGUI; 2 | using Rampastring.XNAUI; 3 | 4 | namespace Ra2Client.DXGUI.Multiplayer.CnCNet 5 | { 6 | /// 7 | /// A panel that hides itself if it's clicked while none of its children 8 | /// are the focus of input. 9 | /// 10 | public class PrivateMessagingPanel : DarkeningPanel 11 | { 12 | public PrivateMessagingPanel(WindowManager windowManager) : base(windowManager) 13 | { 14 | } 15 | 16 | public override void OnLeftClick() 17 | { 18 | bool hideControl = true; 19 | 20 | foreach (var child in Children) 21 | { 22 | if (child.IsActive) 23 | { 24 | hideControl = false; 25 | break; 26 | } 27 | } 28 | 29 | if (hideControl) 30 | Hide(); 31 | 32 | base.OnLeftClick(); 33 | } 34 | 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/CnCNet/RecentPlayerTableRightClickEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Ra2Client.Online; 3 | 4 | namespace Ra2Client.DXGUI.Multiplayer.CnCNet 5 | { 6 | public class RecentPlayerTableRightClickEventArgs : EventArgs 7 | { 8 | public IRCUser IrcUser { get; set; } 9 | 10 | public RecentPlayerTableRightClickEventArgs(IRCUser ircUser) 11 | { 12 | IrcUser = ircUser; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/ChatBoxCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby 4 | { 5 | /// 6 | /// A command that can be executed by typing a message starting with / on 7 | /// a multiplayer game lobby's chat box. 8 | /// 9 | public class ChatBoxCommand 10 | { 11 | public ChatBoxCommand(string command, string description, bool hostOnly, Action action) 12 | { 13 | Command = command; 14 | Description = description; 15 | HostOnly = hostOnly; 16 | Action = action; 17 | } 18 | 19 | public string Command { get; private set; } 20 | public string Description { get; private set; } 21 | public bool HostOnly { get; private set; } 22 | public Action Action { get; private set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/CommandHandlers/CommandHandlerBase.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby.CommandHandlers 2 | { 3 | public abstract class CommandHandlerBase 4 | { 5 | public CommandHandlerBase(string commandName) 6 | { 7 | CommandName = commandName; 8 | } 9 | 10 | public string CommandName { get; private set; } 11 | 12 | public abstract bool Handle(string sender, string message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/CommandHandlers/IntCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby.CommandHandlers 4 | { 5 | public class IntCommandHandler : CommandHandlerBase 6 | { 7 | public IntCommandHandler(string commandName, Action handler) : base(commandName) 8 | { 9 | this.handler = handler; 10 | } 11 | 12 | Action handler; 13 | 14 | public override bool Handle(string sender, string message) 15 | { 16 | if (message.Length < CommandName.Length + 1) 17 | return false; 18 | 19 | if (message.StartsWith(CommandName)) 20 | { 21 | int value; 22 | bool success = int.TryParse(message.Substring(CommandName.Length + 1), out value); 23 | 24 | if (success) 25 | { 26 | handler(sender, value); 27 | return true; 28 | } 29 | } 30 | 31 | return false; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/CommandHandlers/IntNotificationHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby.CommandHandlers 4 | { 5 | public class IntNotificationHandler : CommandHandlerBase 6 | { 7 | public IntNotificationHandler(string commandName, Action> action, 8 | Action innerAction) : base(commandName) 9 | { 10 | this.action = action; 11 | this.innerAction = innerAction; 12 | } 13 | 14 | Action> action; 15 | Action innerAction; 16 | 17 | public override bool Handle(string sender, string message) 18 | { 19 | if (message.StartsWith(CommandName)) 20 | { 21 | string intPart = message.Substring(CommandName.Length + 1); 22 | int value; 23 | bool success = int.TryParse(intPart, out value); 24 | 25 | action(sender, value, innerAction); 26 | return true; 27 | } 28 | 29 | return false; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/CommandHandlers/NoParamCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby.CommandHandlers 4 | { 5 | /// 6 | /// A command handler that handles a command that has no parameter aside from the sender. 7 | /// 8 | public class NoParamCommandHandler : CommandHandlerBase 9 | { 10 | public NoParamCommandHandler(string commandName, Action commandHandler) : base(commandName) 11 | { 12 | this.commandHandler = commandHandler; 13 | } 14 | 15 | Action commandHandler; 16 | 17 | public override bool Handle(string sender, string message) 18 | { 19 | if (message == CommandName) 20 | { 21 | commandHandler(sender); 22 | return true; 23 | } 24 | 25 | return false; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/CommandHandlers/NotificationHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby.CommandHandlers 4 | { 5 | public class NotificationHandler : CommandHandlerBase 6 | { 7 | public NotificationHandler(string commandName, Action action, 8 | Action innerAction) : base(commandName) 9 | { 10 | this.action = action; 11 | this.innerAction = innerAction; 12 | } 13 | 14 | Action action; 15 | Action innerAction; 16 | 17 | public override bool Handle(string sender, string message) 18 | { 19 | if (message == CommandName) 20 | { 21 | action(sender, innerAction); 22 | return true; 23 | } 24 | 25 | return false; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/CommandHandlers/StringCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby.CommandHandlers 4 | { 5 | class StringCommandHandler : CommandHandlerBase 6 | { 7 | public StringCommandHandler(string commandName, Action commandHandler) : base(commandName) 8 | { 9 | this.commandHandler = commandHandler; 10 | } 11 | 12 | private Action commandHandler; 13 | 14 | public override bool Handle(string sender, string message) 15 | { 16 | if (message.Length < CommandName.Length + 1) 17 | return false; 18 | 19 | if (message.StartsWith(CommandName)) 20 | { 21 | string parameters = message.Substring(CommandName.Length + 1); 22 | 23 | commandHandler.Invoke(sender, parameters); 24 | //commandHandler(sender, message.Substring(CommandName.Length + 1)); 25 | return true; 26 | } 27 | 28 | return false; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/DropDownDataWriteMode.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby 2 | { 3 | /// 4 | /// An enum for controlling how the game lobbies' 5 | /// drop-down controls' data should be written into the spawn INI. 6 | /// 7 | public enum DropDownDataWriteMode 8 | { 9 | /// 10 | /// The 0-based selected index of the drop-down control will 11 | /// be written into the INI. 12 | /// 13 | INDEX, 14 | 15 | /// 16 | /// If index 0 is selected, "false" will be written. 17 | /// Otherwise the client will write "true". 18 | /// 19 | BOOLEAN, 20 | 21 | /// 22 | /// The dropdown value displayed in the UI will 23 | /// be written into the INI. 24 | /// 25 | STRING, 26 | 27 | /// 28 | /// The dropdown value is filename of a mapcode INI file, which will be applied to the map. 29 | /// Nothing is written to spawn INI. 30 | /// 31 | MAPCODE 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/GameModeMapFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Ra2Client.Domain.Multiplayer; 5 | 6 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby 7 | { 8 | public class GameModeMapFilter 9 | { 10 | public Func> GetGameModeMaps; 11 | 12 | public GameModeMapFilter(Func> filterAction) 13 | { 14 | GetGameModeMaps = filterAction; 15 | } 16 | 17 | public bool Any() => GetGameModeMaps().Any(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/GameType.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.DXGUI.Multiplayer.GameLobby 2 | { 3 | public enum GameType 4 | { 5 | Undefined, 6 | FFA, 7 | TeamGame, 8 | Coop 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/GameLobby/SkirmishLobby.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/DXGUI/Multiplayer/GameLobby/SkirmishLobby.cs -------------------------------------------------------------------------------- /RA2Client/DXGUI/Multiplayer/TeamStartMappingsPanel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Ra2Client.Domain.Multiplayer; 5 | using Rampastring.XNAUI; 6 | using Rampastring.XNAUI.XNAControls; 7 | 8 | namespace Ra2Client.DXGUI.Multiplayer 9 | { 10 | public class TeamStartMappingsPanel : XNAPanel 11 | { 12 | public event EventHandler MappingChanged; 13 | 14 | public TeamStartMappingsPanel(WindowManager windowManager) : base(windowManager) 15 | { 16 | DrawBorders = false; 17 | } 18 | 19 | public List GetTeamStartMappingPanels() => 20 | Children.Select(c => c as TeamStartMappingPanel).ToList(); 21 | 22 | public void EnableControls(bool enable) => 23 | GetTeamStartMappingPanels().ForEach(panel => panel.EnableControls(enable)); 24 | 25 | public List GetTeamStartMappings() 26 | { 27 | return GetTeamStartMappingPanels() 28 | .Select(panel => panel.GetTeamStartMapping()) 29 | .Where(mapping => mapping.IsValid) 30 | .ToList(); 31 | } 32 | 33 | public void AddMappingPanel(TeamStartMappingPanel teamStartMappingPanel) 34 | { 35 | teamStartMappingPanel.OptionsChanged += (sender, args) => MappingChanged?.Invoke(sender, args); 36 | AddChild(teamStartMappingPanel); 37 | } 38 | 39 | public void SetTeamStartMappings(List teamStartMappings) 40 | { 41 | var teamStartMappingPanels = GetTeamStartMappingPanels(); 42 | for (int i = 0; i < teamStartMappingPanels.Count; i++) 43 | { 44 | if (teamStartMappings.Count <= i) 45 | { 46 | teamStartMappingPanels[i].ClearSelections(); 47 | continue; 48 | } 49 | 50 | var teamStartMapping = teamStartMappings[i]; 51 | teamStartMappingPanels[i].SetTeamStartMapping(teamStartMapping); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/CnCNet/ExtendedHttpClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Http; 3 | using System.Threading.Tasks; 4 | 5 | namespace Ra2Client.Domain.Multiplayer.CnCNet 6 | { 7 | /// 8 | /// A web client that supports customizing the timeout of the request. 9 | /// 10 | class ExtendedHttpClient 11 | { 12 | private readonly HttpClient httpClient; 13 | 14 | public ExtendedHttpClient() : this(timeout: 10000) { } 15 | 16 | public ExtendedHttpClient(int timeout) 17 | { 18 | var handler = new HttpClientHandler(); 19 | httpClient = new HttpClient(handler) 20 | { 21 | Timeout = TimeSpan.FromMilliseconds(timeout) 22 | }; 23 | } 24 | 25 | public async Task GetStringAsync(Uri address) 26 | { 27 | return await httpClient.GetStringAsync(address); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/CnCNet/HostedCnCNetGame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.CnCNet 4 | { 5 | public class HostedCnCNetGame : GenericHostedGame 6 | { 7 | public HostedCnCNetGame() { } 8 | 9 | public HostedCnCNetGame(string channelName, string revision, string gamever, int maxPlayers, 10 | string roomName, bool passworded, 11 | bool tunneled, 12 | string[] players, string adminName, string mapName, string gameMode) 13 | { 14 | ChannelName = channelName; 15 | Revision = revision; 16 | GameVersion = gamever; 17 | MaxPlayers = maxPlayers; 18 | RoomName = roomName; 19 | Passworded = passworded; 20 | Tunneled = tunneled; 21 | Players = players; 22 | HostName = adminName; 23 | Map = mapName; 24 | GameMode = gameMode; 25 | } 26 | 27 | public string ChannelName { get; set; } 28 | public string Revision { get; set; } 29 | public bool Tunneled { get; set; } 30 | public bool IsLadder { get; set; } 31 | public string MatchID { get; set; } 32 | public CnCNetTunnel TunnelServer { get; set; } 33 | 34 | public override int Ping => TunnelServer.PingInMs; 35 | 36 | public override bool Equals(GenericHostedGame other) => 37 | other is HostedCnCNetGame hostedCnCNetGame ? 38 | string.Equals(hostedCnCNetGame.ChannelName, ChannelName, StringComparison.InvariantCultureIgnoreCase) : 39 | base.Equals(other); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/CnCNet/MapEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.CnCNet 4 | { 5 | public class MapEventArgs : EventArgs 6 | { 7 | public MapEventArgs(Map map) 8 | { 9 | Map = map; 10 | } 11 | 12 | public Map Map { get; private set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/CnCNet/SHA1EventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.CnCNet 4 | { 5 | public class SHA1EventArgs : EventArgs 6 | { 7 | public SHA1EventArgs(string sha1, string mapName) 8 | { 9 | SHA1 = sha1; 10 | MapName = mapName; 11 | } 12 | 13 | public string SHA1 { get; private set; } 14 | 15 | public string MapName { get; private set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/CoopHouseInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Domain.Multiplayer 2 | { 3 | /// 4 | /// Holds information about enemy houses in a co-op map. 5 | /// 6 | public struct CoopHouseInfo 7 | { 8 | public CoopHouseInfo(int side, int color, int startingLocation) 9 | { 10 | Side = side; 11 | Color = color; 12 | StartingLocation = startingLocation; 13 | } 14 | 15 | /// 16 | /// The index of the enemy house's side. 17 | /// 18 | public int Side; 19 | 20 | /// 21 | /// The index of the enemy house's color. 22 | /// 23 | public int Color; 24 | 25 | /// 26 | /// The starting location waypoint of the enemy house. 27 | /// 28 | public int StartingLocation; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/CoopMapInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | using Rampastring.Tools; 5 | 6 | namespace Ra2Client.Domain.Multiplayer 7 | { 8 | public class CoopMapInfo 9 | { 10 | [JsonProperty] 11 | public List EnemyHouses = new List(); 12 | [JsonProperty] 13 | public List AllyHouses = new List(); 14 | [JsonProperty] 15 | public List DisallowedPlayerSides = new List(); 16 | [JsonProperty] 17 | public List DisallowedPlayerColors = new List(); 18 | [JsonProperty] 19 | public List DisallowedPlayerStarts = new List(); 20 | public void SetHouseInfos(IniSection iniSection) 21 | { 22 | EnemyHouses = GetGenericHouseInfo(iniSection, "EnemyHouse"); 23 | AllyHouses = GetGenericHouseInfo(iniSection, "AllyHouse"); 24 | } 25 | 26 | private List GetGenericHouseInfo(IniSection iniSection, string keyName) 27 | { 28 | var houseList = new List(); 29 | 30 | for (int i = 0; ; i++) 31 | { 32 | string[] houseInfo = iniSection.GetStringValue(keyName + i, string.Empty).Split( 33 | [','], StringSplitOptions.RemoveEmptyEntries); 34 | 35 | if (houseInfo.Length == 0) 36 | break; 37 | 38 | int[] info = Conversions.IntArrayFromStringArray(houseInfo); 39 | var chInfo = new CoopHouseInfo(info[0], info[1], info[2]); 40 | 41 | houseList.Add(new CoopHouseInfo(info[0], info[1], info[2])); 42 | } 43 | 44 | return houseList; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/CustomMapCache.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Text.Json.Serialization; 3 | 4 | namespace Ra2Client.Domain.Multiplayer 5 | { 6 | public class CustomMapCache 7 | { 8 | [JsonInclude] 9 | [JsonPropertyName("version")] 10 | public int Version { get; set; } 11 | 12 | [JsonInclude] 13 | [JsonPropertyName("maps")] 14 | public ConcurrentDictionary Maps { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/GameModeMap.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Domain.Multiplayer 2 | { 3 | /// 4 | /// An instance of a Map in a given GameMode 5 | /// 6 | public class GameModeMap 7 | { 8 | public GameMode GameMode { get; } 9 | public Map Map { get; } 10 | public bool IsFavorite { get; set; } 11 | 12 | public GameModeMap(GameMode gameMode, Map map, bool isFavorite) 13 | { 14 | GameMode = gameMode; 15 | Map = map; 16 | IsFavorite = isFavorite; 17 | } 18 | 19 | protected bool Equals(GameModeMap other) => Equals(GameMode, other.GameMode) && Equals(Map, other.Map); 20 | 21 | public override int GetHashCode() 22 | { 23 | unchecked 24 | { 25 | var hashCode = (GameMode != null ? GameMode.GetHashCode() : 0); 26 | hashCode = (hashCode * 397) ^ (Map != null ? Map.GetHashCode() : 0); 27 | hashCode = (hashCode * 397) ^ IsFavorite.GetHashCode(); 28 | return hashCode; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/GameModeMapCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using ClientCore; 4 | 5 | namespace Ra2Client.Domain.Multiplayer 6 | { 7 | public class GameModeMapCollection : List 8 | { 9 | public GameModeMapCollection(IEnumerable gameModes) : 10 | base(gameModes.SelectMany(gm => gm.Maps.Select(map => 11 | new GameModeMap(gm, map, UserINISettings.Instance.IsFavoriteMap(map?.Name, gm.Name)))).Distinct()) 12 | { 13 | } 14 | 15 | public List GameModes => this.Select(gmm => gmm.GameMode).Distinct().ToList(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/GenericHostedGame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ClientCore.CnCNet5; 3 | 4 | namespace Ra2Client.Domain.Multiplayer 5 | { 6 | /// 7 | /// A base class for hosted games. 8 | /// CnCNet and LAN games derive from this. 9 | /// 10 | public abstract class GenericHostedGame : IEquatable 11 | { 12 | public string RoomName { get; set; } 13 | public bool Incompatible { get; set; } 14 | public bool Locked { get; set; } 15 | public bool IsLoadedGame { get; set; } 16 | public bool Passworded { get; set; } 17 | public CnCNetGame Game { get; set; } 18 | public string GameMode { get; set; } 19 | public string Map { get; set; } 20 | public string GameVersion { get; set; } 21 | public string HostName { get; set; } 22 | public string[] Players { get; set; } 23 | 24 | int _maxPlayers = 8; 25 | 26 | public int MaxPlayers 27 | { 28 | get { return _maxPlayers; } 29 | set { _maxPlayers = value; } 30 | } 31 | 32 | public abstract int Ping 33 | { 34 | get; 35 | } 36 | 37 | public DateTime LastRefreshTime { get; set; } 38 | 39 | public int SkillLevel { get; set; } 40 | 41 | public virtual bool Equals(GenericHostedGame other) => 42 | string.Equals(RoomName, other?.RoomName, StringComparison.InvariantCultureIgnoreCase); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/ClientIntCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.LAN 4 | { 5 | public class ClientIntCommandHandler : LANClientCommandHandler 6 | { 7 | public ClientIntCommandHandler(string commandName, Action action) : base(commandName) 8 | { 9 | this.action = action; 10 | } 11 | 12 | private Action action; 13 | 14 | public override bool Handle(string message) 15 | { 16 | if (!message.StartsWith(CommandName)) 17 | return false; 18 | 19 | if (message.Length < CommandName.Length + 2) 20 | return false; 21 | 22 | int value; 23 | bool success = int.TryParse(message.Substring(CommandName.Length + 1), out value); 24 | 25 | if (!success) 26 | return false; 27 | 28 | action(value); 29 | return true; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/ClientNoParamCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.LAN 4 | { 5 | /// 6 | /// A command handler that has no parameters. 7 | /// 8 | class ClientNoParamCommandHandler : LANClientCommandHandler 9 | { 10 | public ClientNoParamCommandHandler(string commandName, Action commandHandler) : base(commandName) 11 | { 12 | this.commandHandler = commandHandler; 13 | } 14 | 15 | Action commandHandler; 16 | 17 | public override bool Handle(string message) 18 | { 19 | if (message != CommandName) 20 | return false; 21 | 22 | commandHandler(); 23 | return true; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/ClientStringCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.LAN 4 | { 5 | public class ClientStringCommandHandler : LANClientCommandHandler 6 | { 7 | public ClientStringCommandHandler(string commandName, Action action) : base(commandName) 8 | { 9 | this.action = action; 10 | } 11 | 12 | Action action; 13 | 14 | public override bool Handle(string message) 15 | { 16 | if (!message.StartsWith(CommandName)) 17 | return false; 18 | 19 | action(message.Substring(CommandName.Length + 1)); 20 | return true; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/HostedLANGame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using ClientCore; 4 | using ClientCore.CnCNet5; 5 | using Ra2Client.Domain.Multiplayer; 6 | using Rampastring.Tools; 7 | 8 | namespace Ra2Client.Domain.LAN 9 | { 10 | class HostedLANGame : GenericHostedGame 11 | { 12 | public IPEndPoint EndPoint { get; set; } 13 | public string LoadedGameID { get; set; } 14 | 15 | public TimeSpan TimeWithoutRefresh { get; set; } 16 | 17 | public override int Ping 18 | { 19 | get 20 | { 21 | return -1; 22 | } 23 | } 24 | 25 | public bool SetDataFromStringArray(GameCollection gc, string[] parameters) 26 | { 27 | if (parameters.Length != 9) 28 | { 29 | Logger.Log("Ignoring LAN GAME message because of an incorrect number of parameters."); 30 | return false; 31 | } 32 | 33 | if (parameters[0] != ProgramConstants.LAN_PROTOCOL_REVISION) 34 | return false; 35 | 36 | GameVersion = parameters[1]; 37 | Incompatible = GameVersion != ProgramConstants.GAME_VERSION; 38 | Game = gc.GameList.Find(g => g.InternalName.ToUpper() == parameters[2]); 39 | if (Game == null) 40 | return false; 41 | Map = parameters[3]; 42 | GameMode = parameters[4]; 43 | LoadedGameID = parameters[5]; 44 | string[] players = parameters[6].Split(','); 45 | Players = players; 46 | if (players.Length == 0) 47 | return false; 48 | HostName = players[0]; 49 | Locked = Conversions.IntFromString(parameters[7], 1) > 0; 50 | IsLoadedGame = Conversions.IntFromString(parameters[8], 0) > 0; 51 | LastRefreshTime = DateTime.Now; 52 | TimeWithoutRefresh = TimeSpan.Zero; 53 | RoomName = HostName + "'s Game"; 54 | 55 | return true; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/LANClientCommandHandler.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Domain.Multiplayer.LAN 2 | { 3 | public abstract class LANClientCommandHandler 4 | { 5 | public LANClientCommandHandler(string commandName) 6 | { 7 | CommandName = commandName; 8 | } 9 | 10 | public string CommandName { get; private set; } 11 | 12 | public abstract bool Handle(string message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/LANColor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | namespace Ra2Client.Domain.LAN 4 | { 5 | public class LANColor 6 | { 7 | public LANColor(string name, Color xnaColor) 8 | { 9 | Name = name; 10 | XNAColor = xnaColor; 11 | } 12 | 13 | public string Name { get; private set; } 14 | public Color XNAColor { get; private set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/LANLobbyUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using Microsoft.Xna.Framework.Graphics; 4 | 5 | namespace Ra2Client.Domain.Multiplayer.LAN 6 | { 7 | public class LANLobbyUser 8 | { 9 | public LANLobbyUser(string name, Texture2D gameTexture, IPEndPoint endPoint) 10 | { 11 | Name = name; 12 | GameTexture = gameTexture; 13 | EndPoint = endPoint; 14 | } 15 | 16 | public string Name { get; private set; } 17 | public Texture2D GameTexture { get; private set; } 18 | public IPEndPoint EndPoint { get; private set; } 19 | public TimeSpan TimeWithoutRefresh { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/LANServerCommandHandler.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Domain.Multiplayer.LAN 2 | { 3 | public abstract class LANServerCommandHandler 4 | { 5 | public LANServerCommandHandler(string commandName) 6 | { 7 | CommandName = commandName; 8 | } 9 | 10 | public string CommandName { get; private set; } 11 | 12 | public abstract bool Handle(LANPlayerInfo pInfo, string message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/NetworkMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.LAN 4 | { 5 | public class NetworkMessageEventArgs : EventArgs 6 | { 7 | public NetworkMessageEventArgs(string message) 8 | { 9 | Message = message; 10 | } 11 | 12 | public string Message { get; private set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/ServerNoParamCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.LAN 4 | { 5 | public class ServerNoParamCommandHandler : LANServerCommandHandler 6 | { 7 | public ServerNoParamCommandHandler(string commandName, 8 | Action handler) : base(commandName) 9 | { 10 | this.handler = handler; 11 | } 12 | 13 | Action handler; 14 | 15 | public override bool Handle(LANPlayerInfo pInfo, string message) 16 | { 17 | if (message == CommandName) 18 | { 19 | handler(pInfo); 20 | return true; 21 | } 22 | 23 | return false; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/LAN/ServerStringCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Domain.Multiplayer.LAN 4 | { 5 | public class ServerStringCommandHandler : LANServerCommandHandler 6 | { 7 | public ServerStringCommandHandler(string commandName, 8 | Action handler) 9 | : base(commandName) 10 | { 11 | this.handler = handler; 12 | } 13 | 14 | Action handler; 15 | 16 | public override bool Handle(LANPlayerInfo pInfo, string message) 17 | { 18 | if (!message.StartsWith(CommandName) || 19 | message.Length <= CommandName.Length + 1) 20 | return false; 21 | 22 | handler(pInfo, message); 23 | return true; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/SavedGamePlayer.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Domain.Multiplayer 2 | { 3 | public class SavedGamePlayer 4 | { 5 | public string Name { get; set; } 6 | public int ColorIndex { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /RA2Client/Domain/Multiplayer/TeamStartMappingPreset.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text.Json.Serialization; 3 | 4 | namespace Ra2Client.Domain.Multiplayer 5 | { 6 | public class TeamStartMappingPreset 7 | { 8 | [JsonInclude] 9 | [JsonPropertyName("n")] 10 | public string Name { get; set; } 11 | 12 | [JsonInclude] 13 | [JsonPropertyName("m")] 14 | public List TeamStartMappings { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Online/ChannelUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online 4 | { 5 | /// 6 | /// An user on an IRC channel. 7 | /// 8 | public class ChannelUser 9 | { 10 | public ChannelUser(IRCUser ircUser) 11 | { 12 | IRCUser = ircUser; 13 | } 14 | 15 | public IRCUser IRCUser { get; private set; } 16 | 17 | public bool IsAdmin { get; set; } 18 | 19 | public bool IsFriend { get; set; } 20 | 21 | public static int ChannelUserComparison(ChannelUser u1, ChannelUser u2) 22 | { 23 | if (u1.IsAdmin != u2.IsAdmin) 24 | return u1.IsAdmin ? -1 : 1; 25 | 26 | if (u1.IsFriend != u2.IsFriend) 27 | return u1.IsFriend ? -1 : 1; 28 | 29 | return string.Compare(u1.IRCUser.Name, u2.IRCUser.Name, StringComparison.InvariantCultureIgnoreCase); 30 | 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/AttemptedServerEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | /// 6 | /// Event arguments for a server connection attempt. 7 | /// 8 | public class AttemptedServerEventArgs : EventArgs 9 | { 10 | public AttemptedServerEventArgs(string serverName) 11 | { 12 | ServerName = serverName; 13 | } 14 | 15 | public string ServerName { get; private set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/CTCPEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class CTCPEventArgs : EventArgs 6 | { 7 | public CTCPEventArgs(string sender, string channelName, string ctcpMessage) 8 | { 9 | Sender = sender; 10 | ChannelName = channelName; 11 | CTCPMessage = ctcpMessage; 12 | } 13 | 14 | public string Sender { get; private set; } 15 | public string ChannelName { get; private set; } 16 | public string CTCPMessage { get; private set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/ChannelCTCPEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class ChannelCTCPEventArgs : EventArgs 6 | { 7 | public ChannelCTCPEventArgs(string userName, string message) 8 | { 9 | UserName = userName; 10 | Message = message; 11 | } 12 | 13 | public string UserName { get; private set; } 14 | public string Message { get; private set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/ChannelEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class ChannelEventArgs : EventArgs 6 | { 7 | public ChannelEventArgs(string channelName) 8 | { 9 | ChannelName = channelName; 10 | } 11 | 12 | public string ChannelName { get; private set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/ChannelModeEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class ChannelModeEventArgs : EventArgs 6 | { 7 | public ChannelModeEventArgs(string userName, string modeString) 8 | { 9 | UserName = userName; 10 | ModeString = modeString; 11 | } 12 | 13 | public string UserName { get; set; } 14 | public string ModeString { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/ChannelTopicEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class ChannelTopicEventArgs : EventArgs 6 | { 7 | public ChannelTopicEventArgs(string channelName, string topic) 8 | { 9 | ChannelName = channelName; 10 | Topic = topic; 11 | } 12 | 13 | public string ChannelName { get; private set; } 14 | public string Topic { get; private set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/CnCNetPrivateMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class CnCNetPrivateMessageEventArgs : EventArgs 6 | { 7 | public CnCNetPrivateMessageEventArgs(string sender, string message) 8 | { 9 | Sender = sender; 10 | Message = message; 11 | DateTime = DateTime.Now; 12 | } 13 | 14 | public DateTime DateTime { get; set; } 15 | 16 | public string Sender { get; private set; } 17 | 18 | public string Message { get; private set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/ConnectionLostEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class ConnectionLostEventArgs : EventArgs 6 | { 7 | public ConnectionLostEventArgs(string reason) 8 | { 9 | Reason = reason; 10 | } 11 | public string Reason { get; private set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/FavoriteMapEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Ra2Client.Domain.Multiplayer; 3 | 4 | namespace Ra2Client.Online.EventArguments 5 | { 6 | public class FavoriteMapEventArgs : EventArgs 7 | { 8 | public readonly Map Map; 9 | 10 | public FavoriteMapEventArgs(Map map) 11 | { 12 | Map = map; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/GameOptionPresetEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class GameOptionPresetEventArgs : EventArgs 6 | { 7 | public string PresetName { get; } 8 | 9 | public GameOptionPresetEventArgs(string presetName) 10 | { 11 | PresetName = presetName; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/JoinUserEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class JoinUserEventArgs : EventArgs 6 | { 7 | public IRCUser IrcUser { get; } 8 | 9 | public JoinUserEventArgs(IRCUser ircUser) 10 | { 11 | IrcUser = ircUser; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/KickEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class KickEventArgs : EventArgs 6 | { 7 | public KickEventArgs(string channelName, string userName) 8 | { 9 | ChannelName = channelName; 10 | UserName = userName; 11 | } 12 | 13 | public string ChannelName { get; private set; } 14 | public string UserName { get; private set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/MultiplayerNameRightClickedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class MultiplayerNameRightClickedEventArgs : EventArgs 6 | { 7 | public string PlayerName { get; } 8 | 9 | public MultiplayerNameRightClickedEventArgs(string playerName) 10 | { 11 | PlayerName = playerName; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/PrivateCTCPEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class PrivateCTCPEventArgs : EventArgs 6 | { 7 | public PrivateCTCPEventArgs(string sender, string message) 8 | { 9 | Sender = sender; 10 | Message = message; 11 | } 12 | 13 | public string Sender { get; private set; } 14 | 15 | public string Message { get; private set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/PrivateMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Online.EventArguments 2 | { 3 | public class PrivateMessageEventArgs : CnCNetPrivateMessageEventArgs 4 | { 5 | public readonly IRCUser ircUser; 6 | 7 | public PrivateMessageEventArgs(string sender, string message, IRCUser ircUser) : base(sender, message) 8 | { 9 | this.ircUser = ircUser; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/ServerMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | /// 6 | /// Generic event argument class for a IRC server message. 7 | /// 8 | public class ServerMessageEventArgs : EventArgs 9 | { 10 | public ServerMessageEventArgs(string message) 11 | { 12 | Message = message; 13 | } 14 | 15 | public string Message { get; private set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/UnreadMessageCountEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class UnreadMessageCountEventArgs : EventArgs 6 | { 7 | public int UnreadMessageCount { get; set; } 8 | 9 | public UnreadMessageCountEventArgs(int unreadMessageCount) 10 | { 11 | UnreadMessageCount = unreadMessageCount; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/UserAwayEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class UserAwayEventArgs : EventArgs 6 | { 7 | public UserAwayEventArgs(string user, string awayReason) 8 | { 9 | UserName = user; 10 | AwayReason = awayReason; 11 | } 12 | 13 | public string UserName { get; private set; } 14 | 15 | public string AwayReason { get; private set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/UserListEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class UserListEventArgs : EventArgs 6 | { 7 | public UserListEventArgs(string channelName, string[] userNames) 8 | { 9 | ChannelName = channelName; 10 | UserNames = userNames; 11 | } 12 | 13 | public string ChannelName { get; private set; } 14 | public string[] UserNames { get; private set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Online/EventArguments/WhoEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ra2Client.Online.EventArguments 4 | { 5 | public class WhoEventArgs : EventArgs 6 | { 7 | public WhoEventArgs(string ident, string userName, string extraInfo) 8 | { 9 | Ident = ident; 10 | UserName = userName; 11 | ExtraInfo = extraInfo; 12 | } 13 | 14 | public string Ident { get; private set; } 15 | 16 | public string UserName { get; private set; } 17 | public string ExtraInfo { get; private set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /RA2Client/Online/IRCColor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | namespace Ra2Client.Online 4 | { 5 | public class IRCColor 6 | { 7 | public IRCColor(string name, bool selectable, Color xnaColor, int ircColorId) 8 | { 9 | Name = name; 10 | Selectable = selectable; 11 | XnaColor = xnaColor; 12 | IrcColorId = ircColorId; 13 | } 14 | 15 | public string Name { get; private set; } 16 | public bool Selectable { get; private set; } 17 | public Color XnaColor { get; private set; } 18 | public int IrcColorId { get; private set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /RA2Client/Online/IRCUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Ra2Client.Online 5 | { 6 | /// 7 | /// A user on an IRC server. 8 | /// 9 | public class IRCUser : ICloneable 10 | { 11 | public IRCUser() { } 12 | 13 | public IRCUser(string name) 14 | { 15 | Name = name; 16 | } 17 | 18 | public IRCUser(string name, string ident, string host) 19 | { 20 | Name = name; 21 | Ident = ident; 22 | Hostname = host; 23 | } 24 | 25 | public string Name { get; set; } 26 | public string Ident { get; set; } 27 | public string Hostname { get; set; } 28 | public int GameID { get; set; } = -1; 29 | 30 | public List Channels = new List(); 31 | 32 | public object Clone() 33 | { 34 | return MemberwiseClone(); 35 | } 36 | 37 | public bool IsFriend { get; set; } 38 | public bool IsIgnored { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /RA2Client/Online/IUserCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Ra2Client.Online 5 | { 6 | public interface IUserCollection 7 | { 8 | int Count { get; } 9 | 10 | void Add(string username, T item); 11 | void Clear(); 12 | void DoForAllUsers(Action action); 13 | T Find(string username); 14 | LinkedListNode GetFirst(); 15 | void Reinsert(string username); 16 | bool Remove(string username); 17 | } 18 | } -------------------------------------------------------------------------------- /RA2Client/Online/PrivateMessageUser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Ra2Client.Online 4 | { 5 | class PrivateMessageUser 6 | { 7 | public PrivateMessageUser(IRCUser user) 8 | { 9 | IrcUser = user; 10 | } 11 | 12 | public IRCUser IrcUser { get; private set; } 13 | 14 | public List Messages = new List(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RA2Client/Online/QueuedMessageType.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Online 2 | { 3 | /// 4 | /// The type of a CnCNet IRC network message. 5 | /// 6 | public enum QueuedMessageType 7 | { 8 | UNDEFINED, 9 | CHAT_MESSAGE, 10 | SYSTEM_MESSAGE, 11 | GAME_SETTINGS_MESSAGE, 12 | GAME_PLAYERS_MESSAGE, 13 | GAME_PLAYERS_READY_STATUS_MESSAGE, 14 | GAME_LOCKED_MESSAGE, 15 | GAME_GET_READY_MESSAGE, 16 | GAME_NOTIFICATION_MESSAGE, 17 | GAME_HOSTING_MESSAGE, 18 | GAME_CHEATER_MESSAGE, 19 | GAME_BROADCASTING_MESSAGE, 20 | WHOIS_MESSAGE, 21 | INSTANT_MESSAGE, 22 | GAME_PLAYERS_EXTRA_MESSAGE, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /RA2Client/Online/RecentPlayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.Json.Serialization; 3 | 4 | namespace Ra2Client.Online 5 | { 6 | public class RecentPlayer 7 | { 8 | [JsonInclude] 9 | public string PlayerName { get; set; } 10 | 11 | [JsonInclude] 12 | public string GameName { get; set; } 13 | 14 | [JsonInclude] 15 | public DateTime GameTime { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RA2Client/Online/ReunionEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Ra2Client.Online 8 | { 9 | [Serializable] 10 | public struct QueryObj 11 | { 12 | public string id { get; set; } 13 | 14 | public string op { get; set; } 15 | 16 | public string score { get; set; } 17 | 18 | public string key { get; set; } 19 | 20 | public QueryObj(string id, string op, string score, string key) 21 | { 22 | this.id = id; 23 | this.op = op; 24 | this.score = score; 25 | this.key = key; 26 | } 27 | } 28 | 29 | [Serializable] 30 | public struct RatingObejct 31 | { 32 | public string name { get; set; } 33 | 34 | public string score { get; set; } 35 | 36 | public string total { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /RA2Client/Online/Server.cs: -------------------------------------------------------------------------------- 1 | namespace Ra2Client.Online 2 | { 3 | /// 4 | /// A struct containing information on an IRC server. 5 | /// 6 | public struct Server 7 | { 8 | public Server(string host, string name, int[] ports) 9 | { 10 | Host = host; 11 | Name = name; 12 | Ports = ports; 13 | } 14 | 15 | public string Host; 16 | public string Name; 17 | public int[] Ports; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /RA2Client/Online/UnsortedUserCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Ra2Client.Online 5 | { 6 | /// 7 | /// A custom collection that aims to provide quick insertion, 8 | /// removal and lookup operations by using a dictionary. Does not 9 | /// keep the list sorted. 10 | /// 11 | public class UnsortedUserCollection : IUserCollection 12 | { 13 | private Dictionary dictionary = new Dictionary(); 14 | 15 | public int Count => dictionary.Count; 16 | 17 | public void Add(string username, T item) 18 | { 19 | dictionary.Add(username.ToLower(), item); 20 | } 21 | 22 | public void Clear() 23 | { 24 | dictionary.Clear(); 25 | } 26 | 27 | public void DoForAllUsers(Action action) 28 | { 29 | var values = dictionary.Values; 30 | 31 | foreach (T value in values) 32 | { 33 | action(value); 34 | } 35 | } 36 | 37 | public T Find(string username) 38 | { 39 | if (dictionary.TryGetValue(username.ToLower(), out T value)) 40 | return value; 41 | 42 | return default(T); 43 | } 44 | 45 | public LinkedListNode GetFirst() 46 | { 47 | throw new NotImplementedException(); 48 | } 49 | 50 | public void Reinsert(string username) 51 | { 52 | throw new NotImplementedException(); 53 | } 54 | 55 | public bool Remove(string username) 56 | { 57 | return dictionary.Remove(username.ToLower()); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /RA2Client/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Ra2Client": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-NOLOGO" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /RA2Client/RA2Client.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | <_LastSelectedProfileId>E:\Documents\My_File\Clone\Ra2Client\Properties\PublishProfiles\FolderProfile.pubxml 5 | 6 | -------------------------------------------------------------------------------- /RA2Client/Resources/Allied.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/Allied.png -------------------------------------------------------------------------------- /RA2Client/Resources/Soviet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/Soviet.png -------------------------------------------------------------------------------- /RA2Client/Resources/Yuri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/Yuri.png -------------------------------------------------------------------------------- /RA2Client/Resources/chat_ic_lv1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/chat_ic_lv1.png -------------------------------------------------------------------------------- /RA2Client/Resources/chat_ic_lv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/chat_ic_lv2.png -------------------------------------------------------------------------------- /RA2Client/Resources/chat_ic_lv3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/chat_ic_lv3.png -------------------------------------------------------------------------------- /RA2Client/Resources/chat_ic_lv4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/chat_ic_lv4.png -------------------------------------------------------------------------------- /RA2Client/Resources/chat_ic_lv5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/chat_ic_lv5.png -------------------------------------------------------------------------------- /RA2Client/Resources/chat_ic_lv6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/chat_ic_lv6.png -------------------------------------------------------------------------------- /RA2Client/Resources/noMapPreview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/noMapPreview.png -------------------------------------------------------------------------------- /RA2Client/Resources/skillLevel1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/skillLevel1.png -------------------------------------------------------------------------------- /RA2Client/Resources/skillLevel2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/skillLevel2.png -------------------------------------------------------------------------------- /RA2Client/Resources/skillLevel3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/skillLevel3.png -------------------------------------------------------------------------------- /RA2Client/Resources/中立.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/Resources/中立.png -------------------------------------------------------------------------------- /RA2Client/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /RA2Client/clienticon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/RA2Client/clienticon.ico -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 红色警戒2 重聚未来 1.5 开发者文档 2 |
3 | 4 | ![image](https://socialify.git.ci/Snowy-Studio/RF-Client/image?description=1&font=Inter&forks=1&issues=1&language=1&name=1&owner=1&pulls=1&stargazers=1&theme=Auto) 5 | 6 | **本项目基于: [xna-cncnet-client](https://github.com/CnCNet/xna-cncnet-client)** 7 | 8 |
9 | 10 | ## 项目结构 11 | 12 | ### ClientCore 13 | 14 | 这里放的是一些底层的数据结构和方法. 15 | 16 | ### ClientGUI 17 | 18 | 这里放的是三次开发的UI控件. 19 | 20 | ### ClientUpdater 21 | 22 | 这里是更新程序,独立于客户端的. 23 | 24 | ### DTAConfig 25 | 26 | 这里放的主要是设置界面的配置窗口. 27 | 28 | ### Localization 29 | 30 | 这里实现了多语言功能和一些扩展方法. 31 | 32 | ### RA2Client 33 | 34 | 客户端主要项目,大部分界面的实现和业务逻辑位于此. 35 | 36 | ### Rampastring.Tools-2.0.6 37 | 38 | 读写INI和一些封装的方法实现. 39 | 40 | ### Rampastring.XNAUI 41 | 42 | 这里放的是二次开发的UI控件. 43 | 44 | ### RandomMapGenerator 45 | 46 | 这是用来生成随机地图的项目. 47 | 48 | ### Reunion 49 | 50 | 这是用于生成启动游戏的exe. 51 | 52 | ### CnCNet License 53 | 54 | CnCNet Client 55 | Copyright (C) 2022-2024 CnCNet, Rampastring 56 | 57 | This program is free software: you can redistribute it and/or modify 58 | it under the terms of the GNU General Public License as published by 59 | the Free Software Foundation, either version 3 of the License, or 60 | (at your option) any later version. 61 | 62 | This program is distributed in the hope that it will be useful, 63 | but WITHOUT ANY WARRANTY; without even the implied warranty of 64 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 65 | GNU General Public License for more details. 66 | 67 | You should have received a copy of the GNU General Public License 68 | along with this program. If not, see . 69 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: 3 | workflow_dispatch: 4 | permissions: 5 | contents: write 6 | jobs: 7 | publish: 8 | if: github.repository == 'Rampastring/Rampastring.Tools' 9 | runs-on: windows-2022 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@main 13 | with: 14 | fetch-depth: 0 15 | - name: Setup .NET Core SDK 16 | uses: actions/setup-dotnet@main 17 | with: 18 | dotnet-version: '8.x.x' 19 | - name: Install GitVersion 20 | uses: gittools/actions/gitversion/setup@main 21 | with: 22 | versionSpec: '5.x' 23 | - name: Determine Version 24 | uses: gittools/actions/gitversion/execute@main 25 | - name: Pack 26 | run: dotnet pack Rampastring.Tools.csproj --configuration Release -p:AssemblyVersion=$env:GitVersion_AssemblySemVer -p:FileVersion=$env:GitVersion_AssemblySemFileVer -p:InformationalVersion=$env:GitVersion_InformationalVersion -p:PackageVersion=$env:GitVersion_NuGetVersionV2 27 | - name: Push 28 | run: dotnet nuget push bin\Release\*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json 29 | - name: Prerelease 30 | if: ${{ env.GitVersion_PreReleaseTag != '' }} 31 | run: gh release create ${{ format('v{0}', env.GitVersion_SemVer) }} --generate-notes --target ${{ github.sha }} --prerelease 32 | env: 33 | GH_TOKEN: ${{ github.token }} 34 | - name: Release 35 | if: ${{ env.GitVersion_PreReleaseTag == '' }} 36 | run: gh release create ${{ format('v{0}', env.GitVersion_SemVer) }} --generate-notes --target ${{ github.sha }} 37 | env: 38 | GH_TOKEN: ${{ github.token }} -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/BooleanStringStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Rampastring.Tools; 4 | 5 | /// 6 | /// Defines how boolean values are converted to strings when a is written. 7 | /// 8 | [Flags] 9 | public enum BooleanStringStyle 10 | { 11 | /// 12 | /// Write boolean values as "True" and "False". 13 | /// 14 | TRUEFALSE = 0, 15 | 16 | /// 17 | /// Write boolean values as "Yes" and "No". 18 | /// 19 | YESNO = 1, 20 | 21 | /// 22 | /// Write boolean values as "true" and "false". 23 | /// 24 | TRUEFALSE_LOWERCASE = 2, 25 | 26 | /// 27 | /// Write boolean values as "yes" and "no". 28 | /// 29 | YESNO_LOWERCASE = 3, 30 | 31 | /// 32 | /// Write boolean values as "1" and "0". 33 | /// 34 | ONEZERO = 4 35 | } 36 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/IIniFile.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.Tools; 2 | 3 | using System.IO; 4 | using System.Collections.Generic; 5 | 6 | public interface IIniFile 7 | { 8 | bool AllowNewSections { get; set; } 9 | string FileName { get; set; } 10 | 11 | IniFile AddSection(IniSection section); 12 | IniFile AddSection(string sectionName); 13 | IniFile RemoveSection(string sectionName); 14 | IniFile CombineSections(string firstSectionName, string secondSectionName); 15 | IniFile EraseSectionKeys(string sectionName); 16 | bool GetBooleanValue(string section, string key, bool defaultValue); 17 | double GetDoubleValue(string section, string key, double defaultValue); 18 | int GetIntValue(string section, string key, int defaultValue); 19 | string GetPathStringValue(string section, string key, string defaultValue); 20 | IniSection GetSection(string name); 21 | List GetSectionKeys(string sectionName); 22 | List GetSections(); 23 | float GetSingleValue(string section, string key, float defaultValue); 24 | string GetStringValue(string section, string key, string defaultValue); 25 | string GetStringValue(string section, string key, string defaultValue, out bool success); 26 | bool KeyExists(string sectionName, string keyName); 27 | IniFile RemoveKey(string sectionName, string key); 28 | void Parse(); 29 | IniFile Reload(); 30 | bool SectionExists(string sectionName); 31 | IniFile SetBooleanValue(string section, string key, bool value); 32 | IniFile SetDoubleValue(string section, string key, double value); 33 | IniFile SetIntValue(string section, string key, int value); 34 | IniFile SetSingleValue(string section, string key, double value, int decimals); 35 | IniFile SetSingleValue(string section, string key, float value); 36 | IniFile SetSingleValue(string section, string key, float value, int decimals); 37 | IniFile SetStringValue(string section, string key, string value); 38 | IniFile WriteIniFile(); 39 | IniFile WriteIniFile(string filePath); 40 | IniFile WriteIniStream(Stream stream); 41 | } -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/INIProperties/BoolProperty.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.Tools.INIProperties; 2 | 3 | /// 4 | /// A boolean to be parsed from an INI file. 5 | /// 6 | public class BoolProperty : GenericINIProperty, IIniProperty 7 | { 8 | public BoolProperty() : this(false) { } 9 | 10 | public BoolProperty(bool defaultValue) : base(defaultValue) 11 | { 12 | } 13 | 14 | public override void ParseValue(IniFile iniFile, string sectionName, string keyName) 15 | { 16 | Value = iniFile.GetBooleanValue(sectionName, keyName, DefaultValue); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/INIProperties/DoubleProperty.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.Tools.INIProperties; 2 | 3 | /// 4 | /// A double to be parsed from an INI file. 5 | /// 6 | public class DoubleProperty : GenericINIProperty, IIniProperty 7 | { 8 | public DoubleProperty() : this(0.0) { } 9 | 10 | public DoubleProperty(double defaultValue) : base(defaultValue) 11 | { 12 | } 13 | 14 | public override void ParseValue(IniFile iniFile, string sectionName, string keyName) 15 | { 16 | Value = iniFile.GetDoubleValue(sectionName, keyName, DefaultValue); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/INIProperties/EnumProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Rampastring.Tools.INIProperties; 4 | 5 | public class EnumProperty : GenericINIProperty, IIniProperty 6 | { 7 | public EnumProperty() : this((T)Activator.CreateInstance(typeof(T))) { } 8 | 9 | public EnumProperty(T defaultValue) : base(defaultValue) 10 | { 11 | } 12 | 13 | public override void ParseValue(IniFile iniFile, string sectionName, string keyName) 14 | { 15 | Value = (T)Enum.Parse(typeof(T), 16 | iniFile.GetStringValue(sectionName, keyName, DefaultValue.ToString()), true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/INIProperties/GenericINIProperty.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.Tools.INIProperties; 2 | 3 | public abstract class GenericINIProperty : IIniProperty 4 | { 5 | public GenericINIProperty(T defaultValue) 6 | { 7 | DefaultValue = defaultValue; 8 | } 9 | 10 | public T DefaultValue { get; private set; } 11 | 12 | public T Value { get; protected set; } 13 | 14 | public static implicit operator T(GenericINIProperty property) 15 | { 16 | return property.Value; 17 | } 18 | 19 | public abstract void ParseValue(IniFile iniFile, string sectionName, string keyName); 20 | 21 | public override string ToString() 22 | { 23 | return Value.ToString(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/INIProperties/IIniProperty.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.Tools.INIProperties; 2 | 3 | /// 4 | /// An interface for INI properties. 5 | /// 6 | public interface IIniProperty 7 | { 8 | void ParseValue(IniFile iniFile, string sectionName, string keyName); 9 | } 10 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/INIProperties/IntProperty.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.Tools.INIProperties; 2 | 3 | /// 4 | /// An integer to be parsed from an INI file. 5 | /// 6 | public class IntProperty : GenericINIProperty, IIniProperty 7 | { 8 | public IntProperty() : this(0) { } 9 | 10 | public IntProperty(int defaultValue) : base(defaultValue) 11 | { 12 | } 13 | 14 | public override void ParseValue(IniFile iniFile, string sectionName, string keyName) 15 | { 16 | Value = iniFile.GetIntValue(sectionName, keyName, DefaultValue); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/INIProperties/StringProperty.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.Tools.INIProperties; 2 | 3 | /// 4 | /// A string to be parsed from an INI file. 5 | /// 6 | public class StringProperty : GenericINIProperty, IIniProperty 7 | { 8 | public StringProperty() : this(string.Empty) { } 9 | 10 | public StringProperty(string defaultValue) : base(defaultValue) 11 | { 12 | } 13 | 14 | public override void ParseValue(IniFile iniFile, string sectionName, string keyName) 15 | { 16 | Value = iniFile.GetStringValue(sectionName, keyName, DefaultValue); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/IniParseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Rampastring.Tools; 4 | 5 | public class IniParseException : Exception 6 | { 7 | public IniParseException(string message) : base(message) 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2023 Rami "Rampastring" Pasanen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/NativeMethods.txt: -------------------------------------------------------------------------------- 1 | FlashWindowEx -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/README.md: -------------------------------------------------------------------------------- 1 | A C# library that contains generally useful tools and classes like an INI file parser, a logger class, type conversions and such. -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/Rampastring.Tools.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32519.111 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rampastring.Tools", "Rampastring.Tools.csproj", "{9F40961F-535A-480C-93C5-6877ED6A8626}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{226035C5-BDF2-434A-AFE0-883481E51CCF}" 9 | ProjectSection(SolutionItems) = preProject 10 | .editorconfig = .editorconfig 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Any CPU = Debug|Any CPU 16 | Release|Any CPU = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {9F40961F-535A-480C-93C5-6877ED6A8626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {9F40961F-535A-480C-93C5-6877ED6A8626}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {9F40961F-535A-480C-93C5-6877ED6A8626}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {9F40961F-535A-480C-93C5-6877ED6A8626}.Release|Any CPU.Build.0 = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | GlobalSection(ExtensibilityGlobals) = postSolution 28 | SolutionGuid = {15D304AD-C81F-4A6C-A530-8B5896AAB2A9} 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /Rampastring.Tools-2.0.6/WindowFlasher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.Win32; 3 | using Windows.Win32.UI.WindowsAndMessaging; 4 | using Windows.Win32.Foundation; 5 | 6 | namespace Rampastring.Tools; 7 | 8 | public static class WindowFlasher 9 | { 10 | /// 11 | /// Flashes a form's window in the taskbar. 12 | /// 13 | /// The handle of the window to flash. 14 | /// The return value fo FlashWindowEx. 15 | #if NET5_0_OR_GREATER 16 | [System.Runtime.Versioning.SupportedOSPlatform("windows5.1.2600")] 17 | #endif 18 | public static bool FlashWindowEx(IntPtr windowHandle) 19 | { 20 | int cbSize; 21 | 22 | unsafe 23 | { 24 | cbSize = sizeof(FLASHWINFO); 25 | } 26 | 27 | var pfwi = new FLASHWINFO 28 | { 29 | cbSize = (uint)cbSize, 30 | hwnd = (HWND)windowHandle, 31 | dwFlags = FLASHWINFO_FLAGS.FLASHW_ALL | FLASHWINFO_FLAGS.FLASHW_TIMERNOFG, 32 | uCount = uint.MaxValue, 33 | dwTimeout = 0u 34 | }; 35 | 36 | BOOL result = PInvoke.FlashWindowEx(pfwi); 37 | 38 | return result.Value != 0; 39 | } 40 | } -------------------------------------------------------------------------------- /Rampastring.XNAUI/BuildAll.bat: -------------------------------------------------------------------------------- 1 | dotnet build .\Rampastring.XNAUI.csproj -c WindowsDXRelease -------------------------------------------------------------------------------- /Rampastring.XNAUI/Input/IIMEHandler.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.XNAUI.XNAControls; 2 | using System; 3 | 4 | namespace Rampastring.XNAUI.Input; 5 | 6 | /// 7 | /// Interface for outside components implementing Input Method Editor (IME) support. 8 | /// 9 | public interface IIMEHandler 10 | { 11 | /// 12 | /// Determines whether IME is allowed to compose text. 13 | /// 14 | bool TextCompositionEnabled { get; } 15 | 16 | void RegisterXNATextBox(XNATextBox sender, Action handleCharInput); 17 | 18 | void KillXNATextBox(XNATextBox sender); 19 | 20 | void OnSelectedChanged(XNATextBox sender); 21 | void OnTextChanged(XNATextBox sender); 22 | 23 | bool HandleCharInput(XNATextBox sender, char input); 24 | 25 | bool HandleScrollLeftKey(XNATextBox sender); 26 | bool HandleScrollRightKey(XNATextBox sender); 27 | 28 | bool HandleBackspaceKey(XNATextBox sender); 29 | bool HandleDeleteKey(XNATextBox sender); 30 | bool HandleEnterKey(XNATextBox sender); 31 | bool HandleEscapeKey(XNATextBox sender); 32 | 33 | bool GetDrawCompositionText(XNATextBox sender, out string composition, out int compositionCursorPosition); 34 | } 35 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/Input/KeyboardEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Rampastring.XNAUI.Input 4 | { 5 | public class KeyboardEventArgs : EventArgs 6 | { 7 | public KeyboardEventArgs(char character, int lParam) 8 | { 9 | this.Character = character; 10 | this.Param = lParam; 11 | } 12 | 13 | public char Character { get; private set; } 14 | 15 | public int Param { get; private set; } 16 | 17 | public int RepeatCount 18 | { 19 | get { return Param & 0xffff; } 20 | } 21 | 22 | public bool ExtendedKey 23 | { 24 | get { return (Param & (1 << 24)) > 0; } 25 | } 26 | 27 | public bool AltPressed 28 | { 29 | get { return (Param & (1 << 29)) > 0; } 30 | } 31 | 32 | public bool PreviousState 33 | { 34 | get { return (Param & (1 << 30)) > 0; } 35 | } 36 | 37 | public bool TransitionState 38 | { 39 | get { return (Param & (1 << 31)) > 0; } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/NativeMethods.txt: -------------------------------------------------------------------------------- 1 | LoadCursorFromFile 2 | ImmGetContext 3 | ImmAssociateContext 4 | ImmReleaseContext 5 | WM_GETDLGCODE 6 | WM_CHAR 7 | WM_IME_SETCONTEXT 8 | WM_INPUTLANGCHANGE 9 | DLGC_WANTALLKEYS 10 | WINDOW_LONG_PTR_INDEX 11 | //CallWindowProc 12 | //SetWindowLong 13 | //SetWindowLongPtr 14 | LRESULT 15 | WPARAM 16 | LPARAM 17 | WNDPROC -------------------------------------------------------------------------------- /Rampastring.XNAUI/PackAll.bat: -------------------------------------------------------------------------------- 1 | dotnet pack .\Rampastring.XNAUI.csproj -c WindowsDXRelease 2 | dotnet pack .\Rampastring.XNAUI.csproj -c WindowsDXDebug 3 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/PlatformSpecific/IGameWindowManager.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | using System.Windows.Forms; 4 | 5 | 6 | namespace Rampastring.XNAUI.PlatformSpecific; 7 | 8 | internal interface IGameWindowManager 9 | { 10 | 11 | event EventHandler GameWindowClosing; 12 | event EventHandler ClientSizeChanged; 13 | 14 | void AllowClosing(); 15 | #if NET5_0_OR_GREATER 16 | [System.Runtime.Versioning.SupportedOSPlatform("windows5.1.2600")] 17 | #endif 18 | void FlashWindow(); 19 | IntPtr GetWindowHandle(); 20 | void HideWindow(); 21 | void MaximizeWindow(); 22 | void MinimizeWindow(); 23 | void PreventClosing(); 24 | void SetMaximizeBox(bool value); 25 | void SetControlBox(bool value); 26 | void SetIcon(string path); 27 | void ShowWindow(); 28 | int GetWindowWidth(); 29 | int GetWindowHeight(); 30 | void SetFormBorderStyle(FormBorderStyle borderStyle); 31 | 32 | bool HasFocus(); 33 | void CenterOnScreen(); 34 | void SetBorderlessMode(bool value); 35 | } -------------------------------------------------------------------------------- /Rampastring.XNAUI/README.md: -------------------------------------------------------------------------------- 1 | A simple XNA Framework / MonoGame UI library. General-purpose, although mainly used in the CnCNet client: https://github.com/CnCNet/xna-cncnet-client 2 | 3 | Includes its own window management and UI control classes. 4 | 5 | References: 6 | - MonoGame or XNA Game Studio 4.0 Refresh 7 | - Rampastring.Tools 8 | 9 | Compiled versions of MonoGame and Rampastring.Tools are included in the repository. 10 | 11 | For an usage example, see https://github.com/CnCNet/xna-cncnet-client/blob/master/DXMainClient/DXGUI/GameClass.cs 12 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/RMath.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using System; 3 | 4 | namespace Rampastring.XNAUI; 5 | 6 | /// 7 | /// Contains static vector math functions. 8 | /// 9 | public static class RMath 10 | { 11 | /// 12 | /// Returns the angle / direction of a vector in radians. 13 | /// 14 | /// The vector. 15 | public static float AngleFromVector(Vector2 vector) 16 | { 17 | return (float)Math.Atan2(vector.Y, vector.X); 18 | } 19 | 20 | /// 21 | /// Creates and returns a new vector with the given length and angle. 22 | /// 23 | /// The length of the vector. 24 | /// The angle of the vector. 25 | public static Vector2 VectorFromLengthAndAngle(float length, float angle) 26 | { 27 | return new Vector2(length * (float)Math.Cos(angle), length * (float)Math.Sin(angle)); 28 | } 29 | 30 | public static Color MultiplyAlpha(Color color) 31 | { 32 | return new Color((color.A * color.R) / 255, 33 | (color.A * color.G) / 255, 34 | (color.A * color.B) / 255, 35 | color.A); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/Rampastring.XNAUI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32414.248 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rampastring.XNAUI", "Rampastring.XNAUI.csproj", "{3EAF996D-7F03-433B-A9A5-17E69AC97C76}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3EAF996D-7F03-433B-A9A5-17E69AC97C76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3EAF996D-7F03-433B-A9A5-17E69AC97C76}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3EAF996D-7F03-433B-A9A5-17E69AC97C76}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3EAF996D-7F03-433B-A9A5-17E69AC97C76}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {F8EE831B-908F-4F0A-87BB-D97DC5FF5027} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Avatar.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Avatar.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Game.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Game.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.GamerServices.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.GamerServices.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Graphics.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Graphics.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Input.Touch.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Input.Touch.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Net.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Storage.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Storage.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Video.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Video.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Xact.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.Xact.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/References/XNA/Microsoft.Xna.Framework.dll -------------------------------------------------------------------------------- /Rampastring.XNAUI/UISettings.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | 4 | namespace Rampastring.XNAUI; 5 | 6 | /// 7 | /// A class that contains UI-related settings, like default UI colors. 8 | /// 9 | public class UISettings 10 | { 11 | /// 12 | /// The currently active UI settings. 13 | /// 14 | public static UISettings ActiveSettings { get; set; } 15 | 16 | public float TextShadowDistance { get; set; } = 1.0f; 17 | public Color TextShadowColor { get; set; } = Color.Black; 18 | 19 | public Color TextColor { get; set; } = new Color(196, 196, 196); 20 | 21 | public Color SubtleTextColor { get; set; } = Color.Gray; 22 | 23 | public Color AltColor { get; set; } = Color.White; 24 | 25 | public Color ButtonTextColor { get; set; } = new Color(196, 196, 196); 26 | 27 | public Color DisabledItemColor { get; set; } = Color.Gray; 28 | 29 | public Color ButtonHoverColor { get; set; } = Color.White; 30 | 31 | public Color BackgroundColor { get; set; } = Color.Black; 32 | 33 | public Color FocusColor { get; set; } = new Color(64, 64, 64); 34 | 35 | public Color PanelBackgroundColor { get; set; } = new Color(32, 32, 32); 36 | 37 | public Color PanelBorderColor { get; set; } = new Color(196, 196, 196); 38 | 39 | public Texture2D CheckBoxCheckedTexture { get; set; } 40 | 41 | public Texture2D CheckBoxClearTexture { get; set; } 42 | 43 | public Texture2D CheckBoxDisabledCheckedTexture { get; set; } 44 | 45 | public Texture2D CheckBoxDisabledClearTexture { get; set; } 46 | 47 | public Texture2D RatingBoxCheckedTexture { get; set; } 48 | 49 | public Texture2D RatingBoxClearTexture { get; set; } 50 | 51 | public float DefaultAlphaRate = 0.005f; 52 | 53 | public float CheckBoxAlphaRate = 0.05f; 54 | 55 | public float IndicatorAlphaRate = 0.05f; 56 | } 57 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/Callback.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Rampastring.XNAUI.XNAControls; 4 | 5 | /// 6 | /// A callback for storing a delegate and its parameters. 7 | /// 8 | internal class Callback 9 | { 10 | public Callback(Delegate d, object[] args) 11 | { 12 | this.d = d; 13 | this.arguments = args; 14 | } 15 | 16 | private Delegate d; 17 | private object[] arguments; 18 | 19 | public void Invoke() 20 | { 21 | //Logger.Log("Executing callback " + d.Method.Name); 22 | d.DynamicInvoke(arguments); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/ControlDrawMode.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.XNAUI.XNAControls; 2 | 3 | public enum ControlDrawMode 4 | { 5 | /// 6 | /// The control is drawn on the same render target with its parent. 7 | /// 8 | NORMAL, 9 | 10 | /// 11 | /// The control is drawn on its own render target. 12 | /// 13 | UNIQUE_RENDER_TARGET 14 | } 15 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/IControlINIAttributeParser.cs: -------------------------------------------------------------------------------- 1 | using Rampastring.Tools; 2 | 3 | namespace Rampastring.XNAUI.XNAControls; 4 | 5 | /// 6 | /// Provides an interface for an object that can parse 7 | /// and apply custom INI attributes for controls. 8 | /// 9 | public interface IControlINIAttributeParser 10 | { 11 | /// 12 | /// Attempts to parse given key's value and sets the parameter value for the given control. 13 | /// 14 | /// The control that the parsing happens for currently. 15 | /// The INI file that is being read from. 16 | /// The key that is being read. 17 | /// The key's value. 18 | /// Whether the parsing was succesful. 19 | bool ParseINIAttribute(XNAControl control, IniFile iniFile, string key, string value); 20 | } 21 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/MouseEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using System; 3 | 4 | namespace Rampastring.XNAUI.XNAControls; 5 | 6 | public class MouseEventArgs : EventArgs 7 | { 8 | public MouseEventArgs(Point relativeLocation) 9 | { 10 | RelativeLocation = relativeLocation; 11 | } 12 | 13 | /// 14 | /// The point of the mouse cursor relative to the control. 15 | /// 16 | public Point RelativeLocation { get; set; } 17 | } 18 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/XNAControl.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Rampastring.XNAUI/XNAControls/XNAControl.cs -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/XNADropDownItem.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | 4 | namespace Rampastring.XNAUI.XNAControls; 5 | 6 | /// 7 | /// A drop-down / context menu item. 8 | /// 9 | public class XNADropDownItem 10 | { 11 | public Color? TextColor { get; set; } 12 | 13 | public Texture2D Texture { get; set; } 14 | 15 | public string Text { get; set; } 16 | 17 | /// 18 | /// An object for containing custom info in the drop down item. 19 | /// 20 | public object Tag { get; set; } 21 | public bool Selectable { get; set; } = true; 22 | 23 | private float alpha = 1.0f; 24 | public float Alpha 25 | { 26 | get { return alpha; } 27 | set 28 | { 29 | if (value < 0.0f) 30 | alpha = 0.0f; 31 | else if (value > 1.0f) 32 | alpha = 1.0f; 33 | else 34 | alpha = value; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/XNAPasswordBox.cs: -------------------------------------------------------------------------------- 1 | namespace Rampastring.XNAUI.XNAControls; 2 | 3 | /// 4 | /// A text box that displays its characters as a different character 5 | /// (a star by default), regardless of what the characters actually are. 6 | /// In other words, a text box for inputting passwords. 7 | /// 8 | public class XNAPasswordBox : XNATextBox 9 | { 10 | /// 11 | /// The character that is displayed in place of all other characters. 12 | /// 13 | public char VisibleChar { get; set; } 14 | 15 | /// 16 | /// Creates a new XNAPasswordBox. 17 | /// 18 | /// The WindowManager. 19 | public XNAPasswordBox(WindowManager wm) : base(wm) 20 | { 21 | VisibleChar = '*'; 22 | } 23 | 24 | /// 25 | /// Gets or sets the real text of the password box. 26 | /// 27 | public string Password 28 | { 29 | get 30 | { 31 | return base.Text; 32 | } 33 | set 34 | { 35 | Text = value; 36 | } 37 | } 38 | 39 | /// 40 | /// Gets the visible string of the password box. 41 | /// If set, changes the actual text / password in the box. 42 | /// 43 | public override string Text 44 | { 45 | get 46 | { 47 | return new string(VisibleChar, base.Text.Length); 48 | } 49 | 50 | set 51 | { 52 | base.Text = value; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/XNASuggestionTextBox.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using Microsoft.Xna.Framework; 3 | using Rampastring.Tools; 4 | 5 | namespace Rampastring.XNAUI.XNAControls; 6 | 7 | /// 8 | /// A text box that displays a "suggestion" text when it's not active. 9 | /// 10 | public class XNASuggestionTextBox : XNATextBox 11 | { 12 | public XNASuggestionTextBox(WindowManager windowManager) : base(windowManager) 13 | { 14 | } 15 | 16 | public string Suggestion { get; set; } 17 | 18 | private Color? _suggestedTextColor; 19 | 20 | public Color SuggestedTextColor 21 | { 22 | get => _suggestedTextColor ?? UISettings.ActiveSettings.SubtleTextColor; 23 | set => _suggestedTextColor = value; 24 | } 25 | 26 | public override void Initialize() 27 | { 28 | base.Initialize(); 29 | 30 | Text = Suggestion ?? string.Empty; 31 | } 32 | 33 | public override void ParseControlINIAttribute(IniFile iniFile, string key, string value) 34 | { 35 | if (key == "Suggestion") 36 | { 37 | Suggestion = value; 38 | } 39 | 40 | base.ParseControlINIAttribute(iniFile, key, value); 41 | } 42 | 43 | public override Color TextColor 44 | { 45 | get => WindowManager.SelectedControl == this ? base.TextColor : SuggestedTextColor; 46 | set => base.TextColor = value; 47 | } 48 | 49 | public override void OnSelectedChanged() 50 | { 51 | base.OnSelectedChanged(); 52 | 53 | if (WindowManager.SelectedControl == this) 54 | { 55 | if (Text == Suggestion) 56 | Text = string.Empty; 57 | } 58 | else 59 | { 60 | if (string.IsNullOrEmpty(Text)) 61 | Text = Suggestion ?? string.Empty; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Rampastring.XNAUI/XNAControls/XNATextBlock.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Rampastring.Tools; 3 | 4 | namespace Rampastring.XNAUI.XNAControls; 5 | 6 | /// 7 | /// A panel with text. 8 | /// 9 | public class XNATextBlock : XNAPanel 10 | { 11 | public XNATextBlock(WindowManager windowManager) : base(windowManager) 12 | { 13 | } 14 | 15 | public override string Text 16 | { 17 | get 18 | { 19 | return base.Text; 20 | } 21 | 22 | set 23 | { 24 | base.Text = Renderer.FixText(value, FontIndex, Width - TextXMargin * 2).Text; 25 | } 26 | } 27 | 28 | private Color? _textColor; 29 | 30 | public Color TextColor 31 | { 32 | get 33 | { 34 | if (_textColor.HasValue) 35 | return _textColor.Value; 36 | 37 | return UISettings.ActiveSettings.TextColor; 38 | } 39 | set { _textColor = value; } 40 | } 41 | 42 | public int FontIndex { get; set; } 43 | 44 | public int TextXMargin { get; set; } = 3; 45 | 46 | public int TextYPosition { get; set; } = 3; 47 | 48 | public override void ParseControlINIAttribute(IniFile iniFile, string key, string value) 49 | { 50 | switch (key) 51 | { 52 | case "TextColor": 53 | TextColor = AssetLoader.GetColorFromString(value); 54 | return; 55 | } 56 | 57 | base.ParseControlINIAttribute(iniFile, key, value); 58 | } 59 | 60 | public override void Draw(GameTime gameTime) 61 | { 62 | DrawPanel(); 63 | 64 | if (!string.IsNullOrEmpty(Text)) 65 | { 66 | DrawStringWithShadow(Text, FontIndex, 67 | new Vector2(TextXMargin, TextYPosition), TextColor); 68 | } 69 | 70 | if (DrawBorders) 71 | DrawPanelBorders(); 72 | 73 | DrawChildren(gameTime); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /RandomMapGenerator/AbstractMapMember.cs: -------------------------------------------------------------------------------- 1 | using RandomMapGenerator.TileInfo; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace RandomMapGenerator 8 | { 9 | public class AbstractMapMember 10 | { 11 | public string MapUnitName { get; set; } = "empty"; 12 | public bool IsOnMap { get; set; } = false; 13 | public bool Placed { get; set; } = false; 14 | public bool NWConnected { get; set; } = false; 15 | public bool NEConnected { get; set; } = false; 16 | public bool SEConnected { get; set; } = false; 17 | public bool SWConnected { get; set; } = false; 18 | public int Entropy { get; set; } = 50; 19 | public bool IsAllOnVisibleMap { get; set; } = false; 20 | public bool PlayerLocationHasTiberium { get; set; } = false; 21 | public AbstractMapUnit GetAbstractMapUnit() 22 | { 23 | var absMapUnit = new AbstractMapUnit(); 24 | foreach (var pAbsMapUnit in WorkingMap.AbstractMapUnitList) 25 | { 26 | if (MapUnitName == pAbsMapUnit.MapUnitName) 27 | { 28 | absMapUnit = pAbsMapUnit; 29 | } 30 | } 31 | return absMapUnit; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /RandomMapGenerator/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator 7 | { 8 | static class Constants 9 | { 10 | public readonly static string ProgramFolder = Path.Combine(Environment.CurrentDirectory, "Resources\\RandomMapGenerator_RA2\\"); 11 | public static string FileName = "map.yrm"; 12 | public static string SaveFileName = "Output.txt"; 13 | public static string MapPackName = "IsoMapPack5"; 14 | public static string FilePath = ProgramFolder + FileName; 15 | public static string SaveFilePath = ProgramFolder + SaveFileName; 16 | public static string BitMapName = "bitmap.bmp"; 17 | public static string BitMapPath = ProgramFolder + BitMapName; 18 | public static string TemplateMapName = "templateMap.map"; 19 | public static string TemplateMapPath = ProgramFolder + TemplateMapName; 20 | public static string TEMPERATEPath = ProgramFolder + @"TileInfo\TEMPERATE\"; 21 | public static string SNOWPath = ProgramFolder + @"TileInfo\SNOW\"; 22 | public static string URBANPath = ProgramFolder + @"TileInfo\URBAN\"; 23 | public static string NEWURBANPath = ProgramFolder + @"TileInfo\NEWURBAN\"; 24 | public static string LUNARPath = ProgramFolder + @"TileInfo\LUNAR\"; 25 | public static string DESERTPath = ProgramFolder + @"TileInfo\DESERT\"; 26 | 27 | public static int FailureTimes = 10000; 28 | public static string RenderPath = ProgramFolder + @"Map Renderer\CNCMaps.Renderer.exe"; 29 | public static string GamePath = @"D:\Games\YURI\Red Alert 2"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /RandomMapGenerator/NonTileObjects/Aircraft.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator.NonTileObjects 7 | { 8 | public class Aircraft 9 | { 10 | public string Owner; 11 | public string Name; 12 | public int Strength; 13 | public int RelativeX; 14 | public int X; 15 | public int RelativeY; 16 | public int Y; 17 | public int Direction; 18 | public string State; 19 | public string Tag; 20 | public int Veteran; 21 | public int Group; 22 | public int AutocreateNoRecruitable; 23 | public int AutocreateYesRecruitable; 24 | 25 | public void Initialize(string iniValue) 26 | { 27 | string[] values = iniValue.Split(','); 28 | if (values.Count() == 12) 29 | { 30 | Owner = values[0]; 31 | Name = values[1]; 32 | Strength = int.Parse(values[2]); 33 | RelativeX = int.Parse(values[3]) - WorkingMap.StartingX; 34 | RelativeY = int.Parse(values[4]) - WorkingMap.StartingY; 35 | Direction = int.Parse(values[5]); 36 | State = values[6]; 37 | Tag = values[7]; 38 | Veteran = int.Parse(values[8]); 39 | Group = int.Parse(values[9]); 40 | AutocreateNoRecruitable = int.Parse(values[10]); 41 | AutocreateYesRecruitable = int.Parse(values[11]); 42 | } 43 | else 44 | Console.WriteLine("An infantry cannot be parsed."); 45 | } 46 | public Aircraft Clone() 47 | { 48 | return (Aircraft)this.MemberwiseClone(); 49 | } 50 | public string CreateINIValue() 51 | { 52 | return Owner + "," + Name + "," + Strength + "," + X + "," + Y + "," + Direction + "," + State + "," + Tag 53 | + "," + Veteran + "," + Group + "," + AutocreateNoRecruitable + "," + AutocreateYesRecruitable; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /RandomMapGenerator/NonTileObjects/Smudge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator.NonTileObjects 7 | { 8 | public class Smudge 9 | { 10 | public string Name; 11 | public int RelativeX; 12 | public int X; 13 | public int RelativeY; 14 | public int Y; 15 | public int unknown; 16 | 17 | public void Initialize(string iniValue) 18 | { 19 | string[] values = iniValue.Split(','); 20 | if (values.Count() == 4) 21 | { 22 | Name = values[0]; 23 | RelativeX = int.Parse(values[1]) - WorkingMap.StartingX; 24 | RelativeY = int.Parse(values[2]) - WorkingMap.StartingY; 25 | unknown = int.Parse(values[3]); 26 | } 27 | } 28 | public Smudge Clone() 29 | { 30 | return (Smudge)this.MemberwiseClone(); 31 | } 32 | public string CreateINIValue() 33 | { 34 | return Name + "," + X + "," + Y + "," + unknown; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /RandomMapGenerator/NonTileObjects/Terrain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator.NonTileObjects 7 | { 8 | public class Terrain 9 | { 10 | public int RelativeX; 11 | public int X; 12 | public int RelativeY; 13 | public int Y; 14 | public string Name; 15 | 16 | public void Initialize(KeyValuePair iniLine) 17 | { 18 | string key = iniLine.Key; 19 | int length = key.Length; 20 | string x = key.Substring(key.Length - 3, 3); 21 | string y = key.Substring(0, key.Length - 3); 22 | Name = iniLine.Value; 23 | RelativeX = int.Parse(x) - WorkingMap.StartingX; 24 | RelativeY = int.Parse(y) - WorkingMap.StartingY; 25 | } 26 | public Terrain Clone() 27 | { 28 | return (Terrain)this.MemberwiseClone(); 29 | } 30 | public KeyValuePair CreateINILine() 31 | { 32 | string key = Y.ToString() + string.Format("{0:000}", X); 33 | var iniLine = new KeyValuePair(key, Name); 34 | return iniLine; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /RandomMapGenerator/NonTileObjects/Waypoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator.NonTileObjects 7 | { 8 | public class Waypoint 9 | { 10 | public int RelativeX; 11 | public int X; 12 | public int RelativeY; 13 | public int Y; 14 | public int Index; 15 | 16 | public void Initialize(KeyValuePair iniLine) 17 | { 18 | string value = iniLine.Value; 19 | int length = value.Length; 20 | string x = value.Substring(value.Length - 3, 3); 21 | string y = value.Substring(0, value.Length - 3); 22 | Index = int.Parse(iniLine.Key); 23 | RelativeX = int.Parse(x) - WorkingMap.StartingX; 24 | RelativeY = int.Parse(y) - WorkingMap.StartingY; 25 | } 26 | public Waypoint Clone() 27 | { 28 | return (Waypoint)this.MemberwiseClone(); 29 | } 30 | public KeyValuePair CreateINILine() 31 | { 32 | string value = Y.ToString() + string.Format("{0:000}", X); 33 | var iniLine = new KeyValuePair(Index.ToString(),value); 34 | return iniLine; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /RandomMapGenerator/RandomMapGenerator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Library 5 | net6.0-windows7.0 6 | 13.0 7 | enable 8 | disable 9 | true 10 | 11 | 12 | 13 | ..\Bin\Resources\Binaries\ 14 | 15 | 16 | ..\Bin\Resources\Binaries\ 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /RandomMapGenerator/RandomMapGenerator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.35027.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RandomMapGenerator", "RandomMapGenerator.csproj", "{DA3063BB-1B23-4960-843C-55875DC2895C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DA3063BB-1B23-4960-843C-55875DC2895C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DA3063BB-1B23-4960-843C-55875DC2895C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DA3063BB-1B23-4960-843C-55875DC2895C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DA3063BB-1B23-4960-843C-55875DC2895C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {EECFA64B-748D-4C62-8467-A2CB11225C19} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /RandomMapGenerator/Tile/AbstractTileType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator.TileInfo 7 | { 8 | public class AbstractTileType 9 | { 10 | public int TileNum { get; set; } 11 | public int SubTile { get; set; } 12 | public int Z { get; set; } 13 | public bool Used { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /RandomMapGenerator/Tile/FailureAbstractMapUnitRecord.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator.TileInfo 7 | { 8 | public class FailureAbstractMapUnitRecord 9 | { 10 | public int X; 11 | public int Y; 12 | public List Name = new List(); 13 | 14 | public void AddFailureRecord(int x, int y, string name) 15 | { 16 | X = x; 17 | Y = y; 18 | Name.Add(name); 19 | } 20 | public bool IsTargetFailureRecord(int x, int y) 21 | { 22 | if (x == X && y == Y) 23 | return true; 24 | else 25 | return false; 26 | } 27 | //units with the same connection type 28 | public bool IsInFailureRecord(string name) 29 | { 30 | var targetMU = WorkingMap.GetAbstractMapUnitByName(name); 31 | foreach (var n in Name) 32 | { 33 | var thisMU = WorkingMap.GetAbstractMapUnitByName(n); 34 | if (targetMU.NEConnectionType == thisMU.NEConnectionType 35 | && targetMU.SEConnectionType == thisMU.SEConnectionType 36 | && targetMU.NWConnectionType == thisMU.NWConnectionType 37 | && targetMU.SWConnectionType == thisMU.SWConnectionType) 38 | return true; 39 | } 40 | return false; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /RandomMapGenerator/Tile/TileEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace RandomMapGenerator.TileInfo 7 | { 8 | public enum Theater 9 | { 10 | TEMPERATE = 0, 11 | SNOW = 1, 12 | URBAN = 2, 13 | NEWURBAN = 3, 14 | LUNAR = 4, 15 | DESERT = 5 16 | } 17 | enum Common 18 | { 19 | _000_Empty = -1, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Reunion/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Reunion/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Reunion")] 9 | [assembly: AssemblyDescription("重聚未来客户端启动器")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Reunion Client Launcher Ciallo~ (∠・ω< )⌒★")] 13 | [assembly: AssemblyCopyright("Copyright © Snowy Studio 2022-2025")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("60c4767f-c794-4a30-90bb-3d36674f2bac")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | [assembly: AssemblyVersion("1.5.1.0")] 33 | [assembly: AssemblyFileVersion("1.5.1.0")] 34 | [assembly: AssemblyInformationalVersion("1.5.1-beta")] -------------------------------------------------------------------------------- /Reunion/clienticon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/Reunion/clienticon.ico -------------------------------------------------------------------------------- /cncnetchatlobby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/cncnetchatlobby.png -------------------------------------------------------------------------------- /cncnetgamelobby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowy-Studio/RF-Client/449ce4fd7f3e223a853086f0243d08c83f062f2a/cncnetgamelobby.png --------------------------------------------------------------------------------