├── .gitignore
├── ConsoleServer
├── App.config
├── ArgsParser.cs
├── ConsoleServer.csproj
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── Engine
├── Api
│ ├── Client
│ │ ├── Admin
│ │ │ └── ClientSendAdminAction.cs
│ │ ├── ClientApi.cs
│ │ ├── ClientCommand.cs
│ │ ├── ClientCommandId.cs
│ │ ├── Files
│ │ │ ├── ClientAddFileAction.cs
│ │ │ ├── ClientDownloadFileAction.cs
│ │ │ ├── ClientFilePostedCommand.cs
│ │ │ ├── ClientFileRemovedCommand.cs
│ │ │ ├── ClientReadFilePartCommand.cs
│ │ │ ├── ClientRemoveFileAction.cs
│ │ │ └── ClientWriteFilePartCommand.cs
│ │ ├── Messages
│ │ │ ├── ClientOutPrivateMessageCommand.cs
│ │ │ ├── ClientOutRoomMessageCommand.cs
│ │ │ ├── ClientOutSystemMessageCommand.cs
│ │ │ ├── ClientRemoveMessagesCommand.cs
│ │ │ ├── ClientSendMessageAction.cs
│ │ │ └── ClientSendPrivateMessageAction.cs
│ │ ├── Others
│ │ │ ├── ClientEmptyCommand.cs
│ │ │ └── ClientPingResponseCommand.cs
│ │ ├── P2P
│ │ │ ├── ClientConnectToP2PServiceCommand.cs
│ │ │ ├── ClientConnectToPeerAction.cs
│ │ │ ├── ClientConnectToPeerCommand.cs
│ │ │ └── ClientWaitPeerConnectionCommand.cs
│ │ ├── Registrations
│ │ │ ├── ClientRegisterAction.cs
│ │ │ ├── ClientRegistrationResponseCommand.cs
│ │ │ └── ClientUnregistrerAction.cs
│ │ ├── Rooms
│ │ │ ├── ClientCreateRoomAction.cs
│ │ │ ├── ClientDeleteRoomAction.cs
│ │ │ ├── ClientExitFromRoomAction.cs
│ │ │ ├── ClientInviteUsersAction.cs
│ │ │ ├── ClientKickUsersAction.cs
│ │ │ ├── ClientRefreshRoomAction.cs
│ │ │ ├── ClientRoomClosedCommand.cs
│ │ │ ├── ClientRoomOpenedCommand.cs
│ │ │ ├── ClientRoomRefreshedCommand.cs
│ │ │ └── ClientSetRoomAdminAction.cs
│ │ └── Voice
│ │ │ └── ClientPlayVoiceCommand.cs
│ ├── IAction.cs
│ ├── IApi.cs
│ ├── ICommand.cs
│ └── Server
│ │ ├── Admin
│ │ └── ServerAdminCommand.cs
│ │ ├── Files
│ │ ├── ServerAddFileToRoomCommand.cs
│ │ └── ServerRemoveFileFromRoomCommand.cs
│ │ ├── Messages
│ │ ├── ServerRemoveMessagesAction.cs
│ │ ├── ServerSendRoomMessageCommand.cs
│ │ └── ServerSendSystemMessageAction.cs
│ │ ├── Others
│ │ ├── ServerEmptyCommand.cs
│ │ └── ServerPingRequestCommand.cs
│ │ ├── P2P
│ │ ├── ServerIntroduceConnectionsAction.cs
│ │ ├── ServerP2PConnectRequestCommand.cs
│ │ ├── ServerP2PReadyAcceptCommand.cs
│ │ └── ServerSendP2PConnectRequestAction.cs
│ │ ├── Registrations
│ │ ├── ServerRegisterCommand.cs
│ │ ├── ServerRemoveUserAction.cs
│ │ └── ServerUnregisterCommand.cs
│ │ ├── Rooms
│ │ ├── ServerCreateRoomCommand.cs
│ │ ├── ServerDeleteRoomCommand.cs
│ │ ├── ServerExitFromRoomCommand.cs
│ │ ├── ServerInviteUsersCommand.cs
│ │ ├── ServerKickUsersCommand.cs
│ │ ├── ServerRefreshRoomCommand.cs
│ │ └── ServerSetRoomAdminCommand.cs
│ │ ├── ServerApi.cs
│ │ ├── ServerCommand.cs
│ │ └── ServerCommandId.cs
├── Audio
│ ├── IPlayer.cs
│ ├── IRecorder.cs
│ └── OpenAL
│ │ ├── OpenALPlayer.cs
│ │ └── OpenALRecorder.cs
├── Engine.csproj
├── EngineStrongName.snk
├── EventArgs
│ ├── AsyncErrorEventArgs.cs
│ ├── ConnectEventArgs.cs
│ ├── ConnectionEventArgs.cs
│ ├── FileDownloadEventArgs.cs
│ ├── PackageReceivedEventArgs.cs
│ ├── PackageSendedEventArgs.cs
│ ├── PluginEventArgs.cs
│ ├── ReceiveMessageEventArgs.cs
│ ├── RecordedEventArgs.cs
│ ├── RegistrationEventArgs.cs
│ ├── RoomClosedEventArgs.cs
│ ├── RoomOpenedEventArgs.cs
│ ├── RoomRefreshedEventArgs.cs
│ ├── RoomUsersEventArgs.cs
│ └── TrustedCertificatesEventArgs.cs
├── Exceptions
│ ├── ErrorCode.cs
│ └── ModelException.cs
├── Helpers
│ ├── CertificateGenerator.cs
│ ├── Crypter.cs
│ ├── EngineSyncContext.cs
│ ├── EventDispatcher.cs
│ ├── Logger.cs
│ ├── Serializer.cs
│ └── TryLock.cs
├── Model
│ ├── Client
│ │ ├── ClientCertificatesStorage.cs
│ │ ├── ClientGuard.cs
│ │ ├── ClientInitializer.cs
│ │ ├── ClientModel.cs
│ │ ├── ClientNotifier.cs
│ │ └── Entities
│ │ │ ├── ClientChat.cs
│ │ │ ├── ClientRoom.cs
│ │ │ ├── ClientUser.cs
│ │ │ └── ClientVoiceRoom.cs
│ ├── Common
│ │ ├── CertificatesStorage.cs
│ │ ├── Dto
│ │ │ ├── BinNullable.cs
│ │ │ ├── ColorDto.cs
│ │ │ ├── FileDescriptionDto.cs
│ │ │ ├── MessageDto.cs
│ │ │ ├── RoomDto.cs
│ │ │ └── UserDto.cs
│ │ ├── Entities
│ │ │ ├── AudioQuality.cs
│ │ │ ├── Chat.cs
│ │ │ ├── DownloadingFile.cs
│ │ │ ├── FileDescription.cs
│ │ │ ├── FileId.cs
│ │ │ ├── Message.cs
│ │ │ ├── PostedFile.cs
│ │ │ ├── Room.cs
│ │ │ ├── RoomType.cs
│ │ │ ├── SoundPack.cs
│ │ │ ├── SystemMessageId.cs
│ │ │ ├── User.cs
│ │ │ ├── UserId.cs
│ │ │ └── VoiceRoom.cs
│ │ ├── Guard.cs
│ │ ├── Notifier.cs
│ │ └── NotifierGenerator.cs
│ └── Server
│ │ ├── Entities
│ │ ├── ServerChat.cs
│ │ ├── ServerRoom.cs
│ │ └── ServerVoiceRoom.cs
│ │ ├── ServerGuard.cs
│ │ ├── ServerInitializer.cs
│ │ ├── ServerModel.cs
│ │ └── ServerNotifier.cs
├── Network
│ ├── AsyncClient.cs
│ ├── AsyncPeer.cs
│ ├── AsyncServer.cs
│ ├── CertificateStatus.cs
│ ├── Connection.cs
│ ├── ConnectionInfo.cs
│ ├── P2PService.cs
│ ├── Package.cs
│ ├── Packed.cs
│ ├── Packer.cs
│ ├── Pool.cs
│ ├── RequestQueue.cs
│ ├── ServerBans.cs
│ ├── ServerConnection.cs
│ └── Unpacked.cs
├── Plugins
│ ├── Client
│ │ ├── ClientModelWrapper.cs
│ │ ├── ClientPlugin.cs
│ │ ├── ClientPluginCommand.cs
│ │ └── ClientPluginManager.cs
│ ├── CrossDomainObject.cs
│ ├── Plugin.cs
│ ├── PluginInfo.cs
│ ├── PluginInfoLoader.cs
│ ├── PluginManager.cs
│ └── Server
│ │ ├── ServerModelWrapper.cs
│ │ ├── ServerPlugin.cs
│ │ ├── ServerPluginCommand.cs
│ │ └── ServerPluginManager.cs
├── Properties
│ └── AssemblyInfo.cs
└── packages.config
├── LICENSE
├── Libraries
└── OpenAL.dll
├── Lidgren.Network
├── Documentation
│ ├── ChangedFromV2.txt
│ ├── Discovery.html
│ ├── Improvements.txt
│ ├── PacketLayout.txt
│ ├── SimulatingBadNetwork.html
│ ├── TODO.txt
│ └── Tutorial.html
├── Encryption
│ ├── INetEncryption.cs
│ ├── NetAESEncryption.cs
│ ├── NetBlockEncryptionBase.cs
│ ├── NetDESEncryption.cs
│ ├── NetRC2Encryption.cs
│ ├── NetTripleDESEncryption.cs
│ ├── NetXorEncryption.cs
│ └── NetXteaEncryption.cs
├── Lidgren.Network.csproj
├── LidgrenNetworkStrongName.snk
├── NamespaceDoc.cs
├── NetBigInteger.cs
├── NetBitVector.cs
├── NetBitWriter.cs
├── NetBuffer.Peek.cs
├── NetBuffer.Read.Reflection.cs
├── NetBuffer.Read.cs
├── NetBuffer.Write.Reflection.cs
├── NetBuffer.Write.cs
├── NetBuffer.cs
├── NetClient.cs
├── NetConnection.Handshake.cs
├── NetConnection.Latency.cs
├── NetConnection.MTU.cs
├── NetConnection.cs
├── NetConnectionStatistics.cs
├── NetConnectionStatus.cs
├── NetConstants.cs
├── NetDeliveryMethod.cs
├── NetException.cs
├── NetFragmentationHelper.cs
├── NetFragmentationInfo.cs
├── NetIncomingMessage.cs
├── NetIncomingMessageType.cs
├── NetMessageType.cs
├── NetNatIntroduction.cs
├── NetOutgoingMessage.cs
├── NetPeer.Discovery.cs
├── NetPeer.Fragmentation.cs
├── NetPeer.Internal.cs
├── NetPeer.LatencySimulation.cs
├── NetPeer.Logging.cs
├── NetPeer.MessagePools.cs
├── NetPeer.Send.cs
├── NetPeer.cs
├── NetPeerConfiguration.cs
├── NetPeerStatistics.cs
├── NetPeerStatus.cs
├── NetQueue.cs
├── NetRandom.cs
├── NetReceiverChannelBase.cs
├── NetReliableOrderedReceiver.cs
├── NetReliableSenderChannel.cs
├── NetReliableSequencedReceiver.cs
├── NetReliableUnorderedReceiver.cs
├── NetSRP.cs
├── NetSendResult.cs
├── NetSenderChannelBase.cs
├── NetServer.cs
├── NetStoredReliableMessage.cs
├── NetTime.cs
├── NetTuple.cs
├── NetUPnP.cs
├── NetUnreliableSenderChannel.cs
├── NetUnreliableSequencedReceiver.cs
├── NetUnreliableUnorderedReceiver.cs
├── NetUtility.cs
├── Properties
│ └── AssemblyInfo.cs
└── SenderChannelBase.cs
├── README.md
├── ServerCertificate.cer
├── TCPChat.sln
├── UI
├── App.config
├── App.xaml
├── App.xaml.cs
├── Dialogs
│ ├── AboutProgramDialog.xaml
│ ├── AboutProgramDialog.xaml.cs
│ ├── ConnectDialog.xaml
│ ├── ConnectDialog.xaml.cs
│ ├── CreateRoomDialog.xaml
│ ├── CreateRoomDialog.xaml.cs
│ ├── GenerateCertificateDialog.xaml
│ ├── GenerateCertificateDialog.xaml.cs
│ ├── ServerCertificateConfirmDialog.xaml
│ ├── ServerCertificateConfirmDialog.xaml.cs
│ ├── ServerDialog.xaml
│ ├── ServerDialog.xaml.cs
│ ├── UsersOperationDialog.xaml
│ └── UsersOperationDialog.xaml.cs
├── Images
│ ├── chat.ico
│ ├── chat.png
│ ├── checked.png
│ ├── checkedNotMatch.png
│ ├── notChecked.png
│ ├── voiceOff.png
│ ├── voiceOn.png
│ └── voiceSpeak.png
├── Infrastructure
│ ├── AttachedHelper.cs
│ ├── BoolToVisibilityConverter.cs
│ ├── Command.cs
│ ├── IconToImageSourceConverter.cs
│ ├── KeyBoard.cs
│ ├── Localized.cs
│ ├── Localizer.cs
│ ├── LocalizerStorage.cs
│ ├── PluginSetting.cs
│ ├── RgbToColorConverter.cs
│ └── Settings.cs
├── Localization
│ ├── Localization.en-US.xml
│ ├── Localization.fr-FR.xml
│ └── Localization.ru-RU.xml
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Settings.xml
├── UI.csproj
├── UI.csproj.user
├── UIStrongName.snk
├── View
│ ├── MainView.xaml
│ ├── MainView.xaml.cs
│ ├── PostedFilesView.xaml
│ ├── PostedFilesView.xaml.cs
│ ├── SettingsView.xaml
│ └── SettingsView.xaml.cs
└── ViewModel
│ ├── AudioTabViewModel.cs
│ ├── BaseViewModel.cs
│ ├── ClientTabViewModel.cs
│ ├── LightUserViewModel.cs
│ ├── MainViewModel.cs
│ ├── MessageViewModel.cs
│ ├── PluginInfoViewModel.cs
│ ├── PluginSettingTabViewModel.cs
│ ├── PluginViewModel.cs
│ ├── PostedFilesViewModel.cs
│ ├── RoomViewModel.cs
│ ├── ServerTabViewModel.cs
│ ├── SettingsTabViewModel.cs
│ ├── SettingsViewModel.cs
│ ├── UiCertificateStatus.cs
│ └── UserViewModel.cs
└── screen.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | [Oo]bj/
3 | [Bb]in/
4 |
5 | # mstest test results
6 | TestResults
7 |
8 | ## Ignore Visual Studio temporary files, build results, and
9 | ## files generated by popular Visual Studio add-ons.
10 |
11 | # Vs folder
12 | .vs/
13 |
14 | # User-specific files
15 | *.suo
16 | *.user
17 | *.sln.docstates
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Rr]elase/
22 | x64/
23 | *_i.c
24 | *_p.c
25 | *.ilk
26 | *.meta
27 | *.obj
28 | *.pch
29 | *.pdb
30 | *.pgc
31 | *.pgd
32 | *.rsp
33 | *.sbr
34 | *.tlb
35 | *.tli
36 | *.tlh
37 | *.tmp
38 | *.log
39 | *.vspscc
40 | *.vssscc
41 | .builds
42 |
43 | # Visual C++ cache files
44 | ipch/
45 | *.aps
46 | *.ncb
47 | *.opensdf
48 | *.sdf
49 |
50 | # Visual Studio profiler
51 | *.psess
52 | *.vsp
53 | *.vspx
54 |
55 | # Guidance Automation Toolkit
56 | *.gpState
57 |
58 | # ReSharper is a .NET coding add-in
59 | _ReSharper*
60 |
61 | # NCrunch
62 | *.ncrunch*
63 | .*crunch*.local.xml
64 |
65 | # Installshield output folder
66 | [Ee]xpress
67 |
68 | # DocProject is a documentation generator add-in
69 | DocProject/buildhelp/
70 | DocProject/Help/*.HxT
71 | DocProject/Help/*.HxC
72 | DocProject/Help/*.hhc
73 | DocProject/Help/*.hhk
74 | DocProject/Help/*.hhp
75 | DocProject/Help/Html2
76 | DocProject/Help/html
77 |
78 | # Click-Once directory
79 | publish
80 |
81 | # Publish Web Output
82 | *.Publish.xml
83 |
84 | # NuGet Packages Directory
85 | packages
86 |
87 | # Windows Azure Build Output
88 | csx
89 | *.build.csdef
90 |
91 | # Windows Store app package directory
92 | AppPackages/
93 |
94 | # Others
95 | [Oo]bj
96 | [Bb]in
97 | sql
98 | TestResults
99 | [Tt]est[Rr]esult*
100 | *.Cache
101 | ClientBin
102 | [Ss]tyle[Cc]op.*
103 | ~$*
104 | *.dbmdl
105 | Generated_Code #added for RIA/Silverlight projects
106 |
107 | # Backup & report files from converting an old project file to a newer
108 | # Visual Studio version. Backup files are not needed, because we have git ;-)
109 | _UpgradeReport_Files/
110 | Backup*/
111 | UpgradeLog*.XML
112 |
--------------------------------------------------------------------------------
/ConsoleServer/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ConsoleServer/ArgsParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace ConsoleServer
5 | {
6 | public class ArgsParser
7 | {
8 | public delegate bool TryParse(string str, out T value);
9 |
10 | private Dictionary _params;
11 | private Action _fallback;
12 |
13 | public ArgsParser(string[] args, Action fallback)
14 | {
15 | if (args.Length % 2 != 0)
16 | throw new InvalidOperationException("invalid args count");
17 |
18 | _params = new Dictionary(StringComparer.OrdinalIgnoreCase);
19 | for (int i = 0; i < args.Length; i += 2)
20 | _params.Add(args[i], args[i + 1]);
21 |
22 | _fallback = fallback;
23 | }
24 |
25 | public string GetOrDefault(string key, string def)
26 | {
27 | if (!_params.TryGetValue(key, out string value))
28 | return def;
29 | return value;
30 | }
31 |
32 | public T GetOrDefault(string key, TryParse parser, T def)
33 | {
34 | var valueStr = GetOrDefault(key, null);
35 | if (valueStr == null)
36 | return def;
37 |
38 | if (!parser(valueStr, out T value))
39 | return def;
40 | return value;
41 | }
42 |
43 | public string Get(string key)
44 | {
45 | if (!_params.TryGetValue(key, out string value))
46 | throw CallFallbackAndCreateException("Param not found: " + key);
47 | return value;
48 | }
49 |
50 | public T Get(string key, TryParse parser)
51 | {
52 | var valueStr = Get(key);
53 | if (!parser(valueStr, out T value))
54 | throw CallFallbackAndCreateException("Can't cast " + key + " to " + typeof(T).Name);
55 | return value;
56 | }
57 |
58 | private Exception CallFallbackAndCreateException(string message)
59 | {
60 | _fallback();
61 | return new InvalidOperationException(message);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/ConsoleServer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("ConsoleServer")]
8 | [assembly: AssemblyDescription("TCPChat Console server")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("39-80")]
11 | [assembly: AssemblyProduct("ConsoleServer")]
12 | [assembly: AssemblyCopyright("Copyright © 39-80 2018")]
13 | [assembly: AssemblyTrademark("ThirtyNineEighty")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("41808c4f-3625-424a-b85b-fada4af3239a")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("5.1.0.0")]
35 | [assembly: AssemblyFileVersion("5.1.0.0")]
36 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Admin/ClientSendAdminAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Admin;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api.Client.Admin
7 | {
8 | [Serializable]
9 | public class ClientSendAdminAction : IAction
10 | {
11 | private readonly string _password;
12 | private readonly string _textCommand;
13 |
14 | [SecuritySafeCritical]
15 | public ClientSendAdminAction(string password, string textCommand)
16 | {
17 | if (!ServerAdminCommand.IsTextCommand(textCommand))
18 | throw new ArgumentException("this is not a text command");
19 |
20 | _password = password;
21 | _textCommand = textCommand;
22 | }
23 |
24 | [SecuritySafeCritical]
25 | public void Perform()
26 | {
27 | var messageContent = new ServerAdminCommand.MessageContent { Password = _password, TextCommand = _textCommand };
28 | ClientModel.Client.SendMessage(ServerAdminCommand.CommandId, messageContent);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Engine/Api/Client/ClientCommandId.cs:
--------------------------------------------------------------------------------
1 | namespace Engine.Api.Client
2 | {
3 | // TODO: rus
4 | //Команды для клиента: (формат сообщений XX XX Serialized(this.MessageContent))
5 | //Расшифровка XX XX:
6 | //F 00 00: Регистрация принята
7 | //F 00 01: Регистрация не принята (ник уже существует)
8 |
9 | //F 00 10: Вывести общее сообщение для комнаты
10 | //F 00 11: Вывести личное сообщение
11 | //F 00 13: Вывести системное сообщение
12 | //F 00 14: Remove messages
13 |
14 | //F 00 30: Открыта комната
15 | //F 00 31: Закрыта комната
16 | //F 00 32: Комната обновлена
17 |
18 | //F 00 40: Опубликовать файл
19 | //F 00 41: Файл больше не раздается
20 | //F 00 42: Прочитать часть файла
21 | //F 00 43: Записать часть файла
22 |
23 | //F 00 50: Ожидать прямое соединение
24 | //F 00 51: Выполнить прямое соединение
25 | //F 00 52: Подключится к сервису P2P
26 |
27 | //F 00 60: Воспроизвести голос
28 |
29 | //F 00 FF: Пинг ответ
30 |
31 | //F FF FF: Пустая команда
32 |
33 | enum ClientCommandId : long
34 | {
35 | RegistrationResponse = 0xF0000,
36 |
37 | OutRoomMessage = 0xF0010,
38 | OutPrivateMessage = 0xF0011,
39 | OutSystemMessage = 0xF0013,
40 | RemoveMessages = 0xF0014,
41 |
42 | RoomOpened = 0xF0030,
43 | RoomClosed = 0xF0031,
44 | RoomRefreshed = 0xF0032,
45 |
46 | FilePosted = 0xF0040,
47 | FileRemoved = 0xF0041,
48 | ReadFilePart = 0xF0042,
49 | WriteFilePart = 0xF0043,
50 |
51 | WaitPeerConnection = 0xF0050,
52 | ConnectToPeer = 0xF0051,
53 | ConnectToP2PService = 0xF0052,
54 |
55 | PlayVoice = 0xF0060,
56 |
57 | PingResponce = 0xF00FF,
58 |
59 | Empty = 0xFFFFF
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Files/ClientAddFileAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Files;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.IO;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Client.Files
8 | {
9 | [Serializable]
10 | public class ClientAddFileAction : IAction
11 | {
12 | private readonly string _roomName;
13 | private readonly string _fileName;
14 |
15 | ///
16 | /// Add file to room.
17 | ///
18 | /// Room name.
19 | /// Full path to file.
20 | [SecuritySafeCritical]
21 | public ClientAddFileAction(string roomName, string fileName)
22 | {
23 | if (string.IsNullOrEmpty(roomName))
24 | throw new ArgumentException("roomName");
25 |
26 | if (string.IsNullOrEmpty(fileName))
27 | throw new ArgumentException("fileName");
28 |
29 | _roomName = roomName;
30 | _fileName = fileName;
31 | }
32 |
33 | [SecuritySafeCritical]
34 | public void Perform()
35 | {
36 | var info = new FileInfo(_fileName);
37 | if (!info.Exists)
38 | throw new InvalidOperationException("File not exist.");
39 |
40 | using (var client = ClientModel.Get())
41 | {
42 | var posted = client.Chat.GetOrCreatePostedFile(info, _roomName);
43 | var sendingContent = new ServerAddFileToRoomCommand.MessageContent { RoomName = _roomName, File = posted.File.ToDto() };
44 | ClientModel.Client.SendMessage(ServerAddFileToRoomCommand.CommandId, sendingContent);
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Files/ClientDownloadFileAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Exceptions;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Entities;
4 | using Engine.Network;
5 | using System;
6 | using System.Security;
7 |
8 | namespace Engine.Api.Client.Files
9 | {
10 | [Serializable]
11 | public class ClientDownloadFileAction : IAction
12 | {
13 | private readonly string _roomName;
14 | private readonly FileId _fileId;
15 | private readonly string _savePath;
16 |
17 | ///
18 | /// Download file.
19 | ///
20 | /// Room name where file was posted.
21 | /// File identifier.
22 | /// Path for file saving.
23 | [SecuritySafeCritical]
24 | public ClientDownloadFileAction(string roomName, FileId fileId, string savePath)
25 | {
26 | if (string.IsNullOrEmpty(roomName))
27 | throw new ArgumentException("roomName");
28 |
29 | if (string.IsNullOrEmpty(savePath))
30 | throw new ArgumentException("savePath");
31 |
32 | _roomName = roomName;
33 | _fileId = fileId;
34 | _savePath = savePath;
35 | }
36 |
37 | [SecuritySafeCritical]
38 | public void Perform()
39 | {
40 | using (var client = ClientModel.Get())
41 | {
42 | var chat = client.Chat;
43 | var room = chat.GetRoom(_roomName);
44 |
45 | if (chat.IsFileDownloading(_fileId))
46 | throw new ModelException(ErrorCode.FileAlreadyDownloading, _fileId);
47 |
48 | var file = room.TryGetFile(_fileId);
49 | if (file == null)
50 | throw new ModelException(ErrorCode.FileInRoomNotFound);
51 |
52 | if (chat.User.Equals(file.Id.Owner))
53 | throw new ModelException(ErrorCode.CantDownloadOwnFile);
54 |
55 | chat.AddFileDownload(new DownloadingFile(file, _savePath));
56 |
57 | var sendingContent = new ClientReadFilePartCommand.MessageContent
58 | {
59 | File = file.ToDto(),
60 | Length = AsyncClient.DefaultFilePartSize,
61 | RoomName = _roomName,
62 | StartPartPosition = 0,
63 | };
64 |
65 | ClientModel.Peer.SendMessage(file.Id.Owner, ClientReadFilePartCommand.CommandId, sendingContent);
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Files/ClientFilePostedCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using Engine.Model.Common.Dto;
5 | using Engine.Model.Common.Entities;
6 | using ThirtyNineEighty.BinarySerializer;
7 |
8 | namespace Engine.Api.Client.Files
9 | {
10 | [SecurityCritical]
11 | class ClientFilePostedCommand :
12 | ClientCommand
13 | {
14 | public const long CommandId = (long)ClientCommandId.FilePosted;
15 |
16 | public override long Id
17 | {
18 | [SecuritySafeCritical]
19 | get { return CommandId; }
20 | }
21 |
22 | [SecuritySafeCritical]
23 | protected override void OnRun(MessageContent content, CommandArgs args)
24 | {
25 | if (content.File == null)
26 | throw new ArgumentNullException(nameof(content.File));
27 |
28 | if (string.IsNullOrEmpty(content.RoomName))
29 | throw new ArgumentException(nameof(content.RoomName));
30 |
31 | using (var client = ClientModel.Get())
32 | {
33 | var room = client.Chat.GetRoom(content.RoomName);
34 |
35 | // File may be posted twice, it's allowed
36 | if (!room.IsFileExist(content.File.Id))
37 | room.AddFile(new FileDescription(content.File));
38 | }
39 |
40 | var receiveMessageArgs = new ReceiveMessageEventArgs
41 | {
42 | Type = MessageType.File,
43 | MessageId = Room.SpecificMessageId,
44 | Time = DateTime.UtcNow,
45 | Message = content.File.Name,
46 | Sender = content.File.Id.Owner,
47 | RoomName = content.RoomName,
48 | FileId = content.File.Id,
49 | };
50 |
51 | ClientModel.Notifier.ReceiveMessage(receiveMessageArgs);
52 | }
53 |
54 | [Serializable]
55 | [BinType("ClientFilePosted")]
56 | public class MessageContent
57 | {
58 | [BinField("f")]
59 | public FileDescriptionDto File;
60 |
61 | [BinField("r")]
62 | public string RoomName;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Files/ClientFileRemovedCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using Engine.Model.Common.Entities;
5 | using ThirtyNineEighty.BinarySerializer;
6 |
7 | namespace Engine.Api.Client.Files
8 | {
9 | [SecurityCritical]
10 | class ClientFileRemovedCommand :
11 | ClientCommand
12 | {
13 | public const long CommandId = (long)ClientCommandId.FileRemoved;
14 |
15 | public override long Id
16 | {
17 | [SecuritySafeCritical]
18 | get { return CommandId; }
19 | }
20 |
21 | [SecuritySafeCritical]
22 | protected override void OnRun(MessageContent content, CommandArgs args)
23 | {
24 | if (string.IsNullOrEmpty(content.RoomName))
25 | throw new ArgumentException("content.RoomName");
26 |
27 | using (var client = ClientModel.Get())
28 | {
29 | // Remove file from room
30 | var room = client.Chat.TryGetRoom(content.RoomName);
31 | if (room != null)
32 | room.RemoveFile(content.FileId);
33 | }
34 | }
35 |
36 | [Serializable]
37 | [BinType("ClientFileRemoved")]
38 | public class MessageContent
39 | {
40 | [BinField("r")]
41 | public string RoomName;
42 |
43 | [BinField("f")]
44 | public FileId FileId;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Files/ClientRemoveFileAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Files;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Entities;
4 | using System;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Client.Files
8 | {
9 | [Serializable]
10 | public class ClientRemoveFileAction : IAction
11 | {
12 | private readonly string _roomName;
13 | private readonly FileId _fileId;
14 |
15 | ///
16 | /// Remove posted file from room.
17 | ///
18 | /// Room name that contain removing file.
19 | /// File identifier.
20 | [SecuritySafeCritical]
21 | public ClientRemoveFileAction(string roomName, FileId fileId)
22 | {
23 | if (string.IsNullOrEmpty(roomName))
24 | throw new ArgumentException("roomName");
25 |
26 | _roomName = roomName;
27 | _fileId = fileId;
28 | }
29 |
30 | [SecuritySafeCritical]
31 | public void Perform()
32 | {
33 | using (var client = ClientModel.Get())
34 | client.Chat.RemovePostedFile(_roomName, _fileId);
35 |
36 | var sendingContent = new ServerRemoveFileFromRoomCommand.MessageContent { RoomName = _roomName, FileId = _fileId };
37 | ClientModel.Client.SendMessage(ServerRemoveFileFromRoomCommand.CommandId, sendingContent);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Messages/ClientOutPrivateMessageCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using ThirtyNineEighty.BinarySerializer;
5 |
6 | namespace Engine.Api.Client.Messages
7 | {
8 | [SecurityCritical]
9 | class ClientOutPrivateMessageCommand
10 | : ClientCommand
11 | {
12 | public const long CommandId = (long)ClientCommandId.OutPrivateMessage;
13 |
14 | public override long Id
15 | {
16 | [SecuritySafeCritical]
17 | get { return CommandId; }
18 | }
19 |
20 | protected override bool IsPeerCommand
21 | {
22 | [SecuritySafeCritical]
23 | get { return true; }
24 | }
25 |
26 | [SecuritySafeCritical]
27 | protected override void OnRun(MessageContent content, CommandArgs args)
28 | {
29 | if (content.Text == null)
30 | throw new ArgumentNullException(nameof(content.Text));
31 |
32 | var receiveMessageArgs = new ReceiveMessageEventArgs
33 | {
34 | Type = MessageType.Private,
35 | Time = DateTime.UtcNow,
36 | Message = content.Text,
37 | Sender = args.ConnectionId,
38 | };
39 |
40 | ClientModel.Notifier.ReceiveMessage(receiveMessageArgs);
41 | }
42 |
43 | [Serializable]
44 | [BinType("ClientOutPrivateMessage")]
45 | public class MessageContent
46 | {
47 | [BinField("t")]
48 | public string Text;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Messages/ClientOutRoomMessageCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using Engine.Model.Common.Dto;
5 | using Engine.Model.Common.Entities;
6 | using ThirtyNineEighty.BinarySerializer;
7 |
8 | namespace Engine.Api.Client.Messages
9 | {
10 | [SecurityCritical]
11 | class ClientOutRoomMessageCommand :
12 | ClientCommand
13 | {
14 | public const long CommandId = (long)ClientCommandId.OutRoomMessage;
15 |
16 | public override long Id
17 | {
18 | [SecuritySafeCritical]
19 | get { return CommandId; }
20 | }
21 |
22 | [SecuritySafeCritical]
23 | protected override void OnRun(MessageContent content, CommandArgs args)
24 | {
25 | if (content.Message == null)
26 | throw new ArgumentException("content.Message");
27 |
28 | if (string.IsNullOrEmpty(content.RoomName))
29 | throw new ArgumentException("ontent.RoomName");
30 |
31 | using (var client = ClientModel.Get())
32 | {
33 | var room = client.Chat.GetRoom(content.RoomName);
34 | room.AddMessage(new Message(content.Message));
35 |
36 | var receiveMessageArgs = new ReceiveMessageEventArgs
37 | {
38 | Type = MessageType.Common,
39 | RoomName = content.RoomName,
40 | MessageId = content.Message.Id,
41 | Time = content.Message.Time,
42 | Message = content.Message.Text,
43 | Sender = content.Message.Owner,
44 | };
45 |
46 | ClientModel.Notifier.ReceiveMessage(receiveMessageArgs);
47 | }
48 | }
49 |
50 | [Serializable]
51 | [BinType("ClientOutRoomMessage")]
52 | public class MessageContent
53 | {
54 | [BinField("m")]
55 | public MessageDto Message;
56 |
57 | [BinField("r")]
58 | public string RoomName;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Messages/ClientOutSystemMessageCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using Engine.Model.Common.Entities;
5 | using ThirtyNineEighty.BinarySerializer;
6 |
7 | namespace Engine.Api.Client.Messages
8 | {
9 | [SecurityCritical]
10 | class ClientOutSystemMessageCommand :
11 | ClientCommand
12 | {
13 | public const long CommandId = (long)ClientCommandId.OutSystemMessage;
14 |
15 | public override long Id
16 | {
17 | [SecuritySafeCritical]
18 | get { return CommandId; }
19 | }
20 |
21 | [SecuritySafeCritical]
22 | protected override void OnRun(MessageContent content, CommandArgs args)
23 | {
24 | if (content.Message == SystemMessageId.None)
25 | throw new ArgumentException("content.Message");
26 |
27 | ClientModel.Notifier.ReceiveMessage(new ReceiveMessageEventArgs
28 | {
29 | SystemMessage = content.Message,
30 | SystemMessageFormat = content.FormatParams,
31 | Time = DateTime.UtcNow,
32 | Type = MessageType.System
33 | });
34 | }
35 |
36 | [Serializable]
37 | [BinType("ClientOutSystemMessage")]
38 | public class MessageContent
39 | {
40 | [BinField("m")]
41 | public SystemMessageId Message;
42 |
43 | [BinField("p")]
44 | public string[] FormatParams;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Messages/ClientRemoveMessagesCommand.cs:
--------------------------------------------------------------------------------
1 | using Engine.Exceptions;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Security;
6 | using ThirtyNineEighty.BinarySerializer;
7 |
8 | namespace Engine.Api.Client.Messages
9 | {
10 | public class ClientRemoveMessagesCommand :
11 | ClientCommand
12 | {
13 | public const long CommandId = (long)ClientCommandId.RemoveMessages;
14 |
15 | public override long Id
16 | {
17 | [SecuritySafeCritical]
18 | get { return CommandId; }
19 | }
20 |
21 | [SecuritySafeCritical]
22 | protected override void OnRun(MessageContent content, CommandArgs args)
23 | {
24 | if (string.IsNullOrEmpty(content.RoomName))
25 | throw new ArgumentException("room name is null or empty");
26 |
27 | using (var client = ClientModel.Get())
28 | {
29 | var room = client.Chat.TryGetRoom(content.RoomName);
30 | if (room == null)
31 | throw new ModelException(ErrorCode.RoomNotFound);
32 |
33 | room.RemoveMessages(content.Ids);
34 | }
35 |
36 | var removed = new HashSet(content.Ids);
37 | ClientModel.Notifier.RoomRefreshed(new RoomRefreshedEventArgs(content.RoomName, null, removed));
38 | }
39 |
40 | [Serializable]
41 | [BinType("ClientRemoveMessages")]
42 | public class MessageContent
43 | {
44 | [BinField("r")]
45 | public string RoomName;
46 |
47 | [BinField("i")]
48 | public long[] Ids;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Messages/ClientSendMessageAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Messages;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api.Client.Messages
7 | {
8 | [Serializable]
9 | public class ClientSendMessageAction : IAction
10 | {
11 | private readonly string _roomName;
12 | private readonly long? _messageId;
13 | private readonly string _text;
14 |
15 | ///
16 | /// Send message.
17 | ///
18 | /// Room name.
19 | /// Message text.
20 | [SecuritySafeCritical]
21 | public ClientSendMessageAction(string roomName, string text)
22 | : this(roomName, null, text)
23 | {
24 |
25 | }
26 |
27 | ///
28 | /// Edit message.
29 | ///
30 | /// Room name.
31 | /// Message id which be edited.
32 | /// Message text.
33 | [SecuritySafeCritical]
34 | public ClientSendMessageAction(string roomName, long messageId, string text)
35 | : this(roomName, (long?)messageId, text)
36 | {
37 |
38 | }
39 |
40 | [SecuritySafeCritical]
41 | private ClientSendMessageAction(string roomName, long? messageId, string text)
42 | {
43 | if (string.IsNullOrEmpty(roomName))
44 | throw new ArgumentException("roomName");
45 |
46 | if (string.IsNullOrEmpty(text))
47 | throw new ArgumentNullException("text");
48 |
49 | _roomName = roomName;
50 | _messageId = messageId;
51 | _text = text;
52 | }
53 |
54 | [SecuritySafeCritical]
55 | public void Perform()
56 | {
57 | var sendingContent = new ServerSendRoomMessageCommand.MessageContent { RoomName = _roomName, MessageId = _messageId, Text = _text };
58 | ClientModel.Client.SendMessage(ServerSendRoomMessageCommand.CommandId, sendingContent);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Messages/ClientSendPrivateMessageAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Client;
2 | using Engine.Model.Common.Entities;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api.Client.Messages
7 | {
8 | [Serializable]
9 | public class ClientSendPrivateMessageAction : IAction
10 | {
11 | private readonly UserId _reciverId;
12 | private readonly string _text;
13 |
14 | ///
15 | /// Send private message to user.
16 | ///
17 | /// Reciver id.
18 | /// Message text.
19 | [SecuritySafeCritical]
20 | public ClientSendPrivateMessageAction(UserId reciverId, string text)
21 | {
22 | if (reciverId == UserId.Empty)
23 | throw new ArgumentException(nameof(reciverId));
24 |
25 | if (string.IsNullOrEmpty(text))
26 | throw new ArgumentNullException(nameof(text));
27 |
28 | _reciverId = reciverId;
29 | _text = text;
30 | }
31 |
32 | [SecuritySafeCritical]
33 | public void Perform()
34 | {
35 | var sendingContent = new ClientOutPrivateMessageCommand.MessageContent { Text = _text };
36 | ClientModel.Peer.SendMessage(_reciverId, ClientOutPrivateMessageCommand.CommandId, sendingContent);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Others/ClientEmptyCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Security;
2 |
3 | namespace Engine.Api.Client.Others
4 | {
5 | [SecurityCritical]
6 | class ClientEmptyCommand : ClientCommand
7 | {
8 | public const long CommandId = (long)ClientCommandId.Empty;
9 | public static readonly ClientEmptyCommand Empty = new ClientEmptyCommand();
10 |
11 | public override long Id
12 | {
13 | [SecuritySafeCritical]
14 | get { return CommandId; }
15 | }
16 |
17 | [SecuritySafeCritical]
18 | protected override void OnRun(CommandArgs args)
19 | {
20 |
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Others/ClientPingResponseCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Security;
2 |
3 | namespace Engine.Api.Client.Others
4 | {
5 | [SecurityCritical]
6 | class ClientPingResponseCommand : ClientCommand
7 | {
8 | public const long CommandId = (long)ClientCommandId.PingResponce;
9 |
10 | public override long Id
11 | {
12 | [SecuritySafeCritical]
13 | get { return CommandId; }
14 | }
15 |
16 | [SecuritySafeCritical]
17 | protected override void OnRun(CommandArgs args)
18 | {
19 |
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Engine/Api/Client/P2P/ClientConnectToP2PServiceCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Security;
4 | using Engine.Model.Client;
5 | using ThirtyNineEighty.BinarySerializer;
6 |
7 | namespace Engine.Api.Client.P2P
8 | {
9 | [SecurityCritical]
10 | class ClientConnectToP2PServiceCommand :
11 | ClientCommand
12 | {
13 | public const long CommandId = (long)ClientCommandId.ConnectToP2PService;
14 |
15 | public override long Id
16 | {
17 | [SecuritySafeCritical]
18 | get { return CommandId; }
19 | }
20 |
21 | [SecuritySafeCritical]
22 | protected override void OnRun(MessageContent content, CommandArgs args)
23 | {
24 | var address = ClientModel.Client.RemotePoint.Address;
25 | var endPoint = new IPEndPoint(address, content.Port);
26 |
27 | ClientModel.Peer.ConnectToService(endPoint);
28 | }
29 |
30 | [Serializable]
31 | [BinType("ClientConnectToP2PService")]
32 | public class MessageContent
33 | {
34 | [BinField("p")]
35 | public int Port;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Engine/Api/Client/P2P/ClientConnectToPeerAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.P2P;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Entities;
4 | using System;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Client.P2P
8 | {
9 | public class ClientConnectToPeerAction : IAction
10 | {
11 | private readonly UserId _userId;
12 |
13 | ///
14 | /// Initiate new direct connection to other user.
15 | /// If connection already exist then action do nothing.
16 | ///
17 | /// User nick.
18 | [SecuritySafeCritical]
19 | public ClientConnectToPeerAction(UserId userId)
20 | {
21 | if (userId == UserId.Empty)
22 | throw new ArgumentException(nameof(userId));
23 |
24 | _userId = userId;
25 | }
26 |
27 | [SecuritySafeCritical]
28 | public void Perform()
29 | {
30 | if (ClientModel.Peer.IsConnected(_userId))
31 | {
32 | ClientModel.Logger.WriteDebug("Client already connected to {0}", _userId);
33 | }
34 | else
35 | {
36 | var sendingContent = new ServerP2PConnectRequestCommand.MessageContent { UserId = _userId };
37 | ClientModel.Client.SendMessage(ServerP2PConnectRequestCommand.CommandId, sendingContent);
38 | ClientModel.Logger.WriteDebug("Connecting directly to {0}...", _userId);
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Engine/Api/Client/P2P/ClientConnectToPeerCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Security;
4 | using Engine.Model.Client;
5 | using Engine.Model.Common.Dto;
6 | using ThirtyNineEighty.BinarySerializer;
7 |
8 | namespace Engine.Api.Client.P2P
9 | {
10 | [SecurityCritical]
11 | class ClientConnectToPeerCommand :
12 | ClientCommand
13 | {
14 | public const long CommandId = (long)ClientCommandId.ConnectToPeer;
15 |
16 | public override long Id
17 | {
18 | [SecuritySafeCritical]
19 | get { return CommandId; }
20 | }
21 |
22 | [SecuritySafeCritical]
23 | protected override void OnRun(MessageContent content, CommandArgs args)
24 | {
25 | if (content.RemoteInfo == null)
26 | throw new ArgumentNullException("content.RemoteInfo");
27 |
28 | var peerPoint = new IPEndPoint(new IPAddress(content.IPAddress), content.Port);
29 | ClientModel.Peer.ConnectToPeer(content.RemoteInfo.Id, peerPoint);
30 | ClientModel.Logger.WriteDebug("ClientConnectToPeerCommand: {0}|{1}", content.RemoteInfo.Id, peerPoint.ToString());
31 | }
32 |
33 | [Serializable]
34 | [BinType("ClientConnectToPeer")]
35 | public class MessageContent
36 | {
37 | [BinField("p")]
38 | public int Port;
39 |
40 | [BinField("a")]
41 | public byte[] IPAddress;
42 |
43 | [BinField("u")]
44 | public UserDto RemoteInfo;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Engine/Api/Client/P2P/ClientWaitPeerConnectionCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Security;
4 | using Engine.Api.Server.P2P;
5 | using Engine.Model.Client;
6 | using Engine.Model.Common.Dto;
7 | using ThirtyNineEighty.BinarySerializer;
8 |
9 | namespace Engine.Api.Client.P2P
10 | {
11 | [SecurityCritical]
12 | class ClientWaitPeerConnectionCommand :
13 | ClientCommand
14 | {
15 | public const long CommandId = (long)ClientCommandId.WaitPeerConnection;
16 |
17 | public override long Id
18 | {
19 | [SecuritySafeCritical]
20 | get { return CommandId; }
21 | }
22 |
23 | [SecuritySafeCritical]
24 | protected override void OnRun(MessageContent content, CommandArgs args)
25 | {
26 | if (content.RemoteInfo == null)
27 | throw new ArgumentNullException("content.RemoteInfo");
28 |
29 | var senderPoint = new IPEndPoint(new IPAddress(content.SenderIpAddress), content.SenderPort);
30 | ClientModel.Peer.WaitConnection(senderPoint);
31 |
32 | var sendingContent = new ServerP2PReadyAcceptCommand.MessageContent
33 | {
34 | PeerPort = content.RequestPort,
35 | PeerIPAddress = content.RequestIpAddress,
36 | ReceiverId = content.RemoteInfo.Id
37 | };
38 |
39 | using (var client = ClientModel.Get())
40 | sendingContent.RemoteInfo = new UserDto(client.Chat.User);
41 |
42 | ClientModel.Client.SendMessage(ServerP2PReadyAcceptCommand.CommandId, sendingContent);
43 |
44 | ClientModel.Logger.WriteDebug("ClientWaitPeerConnectionCommand: {0}|{1}|{2}|{3}"
45 | , new IPAddress(sendingContent.PeerIPAddress)
46 | , sendingContent.PeerPort
47 | , sendingContent.ReceiverId
48 | , sendingContent.RemoteInfo.Id
49 | );
50 | }
51 |
52 | [Serializable]
53 | [BinType("ClientWaitPeerConnection")]
54 | public class MessageContent
55 | {
56 | [BinField("u")]
57 | public UserDto RemoteInfo;
58 |
59 | [BinField("sp")]
60 | public int SenderPort;
61 |
62 | [BinField("sa")]
63 | public byte[] SenderIpAddress;
64 |
65 | [BinField("rp")]
66 | public int RequestPort;
67 |
68 | [BinField("ra")]
69 | public byte[] RequestIpAddress;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Registrations/ClientRegisterAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Registrations;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Dto;
4 | using System;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Client.Registrations
8 | {
9 | [Serializable]
10 | public class ClientRegisterAction : IAction
11 | {
12 | ///
13 | /// Send registration request.
14 | ///
15 | [SecuritySafeCritical]
16 | public ClientRegisterAction()
17 | {
18 | }
19 |
20 | [SecuritySafeCritical]
21 | public void Perform()
22 | {
23 | using (var client = ClientModel.Get())
24 | {
25 | var sendingContent = new ServerRegisterCommand.MessageContent { UserDto = new UserDto(client.Chat.User) };
26 | ClientModel.Client.SendMessage(ServerRegisterCommand.CommandId, sendingContent);
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Registrations/ClientRegistrationResponseCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using Engine.Model.Common.Entities;
5 | using ThirtyNineEighty.BinarySerializer;
6 |
7 | namespace Engine.Api.Client.Registrations
8 | {
9 | [SecurityCritical]
10 | class ClientRegistrationResponseCommand :
11 | ClientCommand
12 | {
13 | public const long CommandId = (long)ClientCommandId.RegistrationResponse;
14 |
15 | public override long Id
16 | {
17 | [SecuritySafeCritical]
18 | get { return CommandId; }
19 | }
20 |
21 | [SecuritySafeCritical]
22 | protected override void OnRun(MessageContent content, CommandArgs args)
23 | {
24 | var eventArgs = new RegistrationEventArgs(content.Registered, content.Message);
25 | ClientModel.Notifier.ReceiveRegistrationResponse(eventArgs);
26 | }
27 |
28 | [Serializable]
29 | [BinType("ClientRegistrationResponse")]
30 | public class MessageContent
31 | {
32 | [BinField("r")]
33 | public bool Registered;
34 |
35 | [BinField("m")]
36 | public SystemMessageId Message;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Registrations/ClientUnregistrerAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Registrations;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api.Client.Registrations
7 | {
8 | [Serializable]
9 | public class ClientUnregisterAction : IAction
10 | {
11 | ///
12 | /// Send unregistration request.
13 | ///
14 | [SecuritySafeCritical]
15 | public ClientUnregisterAction()
16 | {
17 | }
18 |
19 | [SecuritySafeCritical]
20 | public void Perform()
21 | {
22 | ClientModel.Client.SendMessage(ServerUnregisterCommand.CommandId);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientCreateRoomAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Rooms;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Entities;
4 | using System;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Client.Rooms
8 | {
9 | [Serializable]
10 | public class ClientCreateRoomAction : IAction
11 | {
12 | private readonly string _roomName;
13 | private readonly RoomType _type;
14 |
15 | ///
16 | /// Creates room on server.
17 | ///
18 | /// Room name.
19 | /// Room type.
20 | [SecuritySafeCritical]
21 | public ClientCreateRoomAction(string roomName, RoomType type)
22 | {
23 | if (string.IsNullOrEmpty(roomName))
24 | throw new ArgumentException("roomName");
25 |
26 | if (type == RoomType.Unknown)
27 | throw new ArgumentException("type");
28 |
29 | _roomName = roomName;
30 | _type = type;
31 | }
32 |
33 | [SecuritySafeCritical]
34 | public void Perform()
35 | {
36 | var sendingContent = new ServerCreateRoomCommand.MessageContent { RoomName = _roomName, Type = _type };
37 | ClientModel.Client.SendMessage(ServerCreateRoomCommand.CommandId, sendingContent);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientDeleteRoomAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Rooms;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api.Client.Rooms
7 | {
8 | [Serializable]
9 | public class ClientDeleteRoomAction : IAction
10 | {
11 | private readonly string _roomName;
12 |
13 | ///
14 | /// Remove room on server.
15 | ///
16 | /// Removing room name.
17 | [SecuritySafeCritical]
18 | public ClientDeleteRoomAction(string roomName)
19 | {
20 | if (string.IsNullOrEmpty(roomName))
21 | throw new ArgumentException("roomName");
22 |
23 | _roomName = roomName;
24 | }
25 |
26 | [SecuritySafeCritical]
27 | public void Perform()
28 | {
29 | var sendingContent = new ServerDeleteRoomCommand.MessageContent { RoomName = _roomName };
30 | ClientModel.Client.SendMessage(ServerDeleteRoomCommand.CommandId, sendingContent);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientExitFromRoomAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Rooms;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api.Client.Rooms
7 | {
8 | [Serializable]
9 | public class ClientExitFromRoomAction : IAction
10 | {
11 | private readonly string _roomName;
12 |
13 | ///
14 | /// Exit from room.
15 | ///
16 | /// Room name.
17 | [SecuritySafeCritical]
18 | public ClientExitFromRoomAction(string roomName)
19 | {
20 | if (string.IsNullOrEmpty(roomName))
21 | throw new ArgumentException("roomName");
22 |
23 | _roomName = roomName;
24 | }
25 |
26 | [SecuritySafeCritical]
27 | public void Perform()
28 | {
29 | var sendingContent = new ServerExitFromRoomCommand.MessageContent { RoomName = _roomName };
30 | ClientModel.Client.SendMessage(ServerExitFromRoomCommand.CommandId, sendingContent);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientInviteUsersAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Rooms;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Entities;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Security;
8 |
9 | namespace Engine.Api.Client.Rooms
10 | {
11 | [Serializable]
12 | public class ClientInviteUsersAction : IAction
13 | {
14 | private readonly string _roomName;
15 | private readonly UserId[] _users;
16 |
17 | ///
18 | /// Invites users to room.
19 | ///
20 | /// Room name.
21 | /// Users to be invited.
22 | [SecuritySafeCritical]
23 | public ClientInviteUsersAction(string roomName, IEnumerable users)
24 | {
25 | if (string.IsNullOrEmpty(roomName))
26 | throw new ArgumentException("roomName");
27 |
28 | if (users == null)
29 | throw new ArgumentNullException("users");
30 |
31 | _roomName = roomName;
32 | _users = users as UserId[] ?? users.ToArray();
33 | }
34 |
35 | [SecuritySafeCritical]
36 | public void Perform()
37 | {
38 | var sendingContent = new ServerInviteUsersCommand.MessageContent { RoomName = _roomName, Users = _users };
39 | ClientModel.Client.SendMessage(ServerInviteUsersCommand.CommandId, sendingContent);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientKickUsersAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Rooms;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Entities;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Security;
8 |
9 | namespace Engine.Api.Client.Rooms
10 | {
11 | [Serializable]
12 | public class ClientKickUsersAction : IAction
13 | {
14 | private readonly string _roomName;
15 | private readonly UserId[] _users;
16 |
17 | ///
18 | /// Remove users from room.
19 | ///
20 | /// Room name.
21 | /// Users to be removed.
22 | [SecuritySafeCritical]
23 | public ClientKickUsersAction(string roomName, IEnumerable users)
24 | {
25 | if (string.IsNullOrEmpty(roomName))
26 | throw new ArgumentException("roomName");
27 |
28 | if (users == null)
29 | throw new ArgumentNullException("users");
30 |
31 | _roomName = roomName;
32 | _users = users as UserId[] ?? users.ToArray();
33 | }
34 |
35 | [SecuritySafeCritical]
36 | public void Perform()
37 | {
38 | var sendingContent = new ServerKickUsersCommand.MessageContent { RoomName = _roomName, Users = _users };
39 | ClientModel.Client.SendMessage(ServerKickUsersCommand.CommandId, sendingContent);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientRefreshRoomAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Rooms;
2 | using Engine.Model.Client;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api.Client.Rooms
7 | {
8 | [Serializable]
9 | public class ClientRefreshRoomAction : IAction
10 | {
11 | private readonly string _roomName;
12 |
13 | ///
14 | /// Send refresh room request on server.
15 | ///
16 | /// Room name.
17 | [SecuritySafeCritical]
18 | public ClientRefreshRoomAction(string roomName)
19 | {
20 | if (string.IsNullOrEmpty(roomName))
21 | throw new ArgumentException("roomName");
22 |
23 | _roomName = roomName;
24 | }
25 |
26 | [SecuritySafeCritical]
27 | public void Perform()
28 | {
29 | var sendingContent = new ServerRefreshRoomCommand.MessageContent { RoomName = _roomName };
30 | ClientModel.Client.SendMessage(ServerRefreshRoomCommand.CommandId, sendingContent);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientRoomClosedCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using ThirtyNineEighty.BinarySerializer;
5 |
6 | namespace Engine.Api.Client.Rooms
7 | {
8 | [SecurityCritical]
9 | class ClientRoomClosedCommand :
10 | ClientCommand
11 | {
12 | public const long CommandId = (long)ClientCommandId.RoomClosed;
13 |
14 | public override long Id
15 | {
16 | [SecuritySafeCritical]
17 | get { return CommandId; }
18 | }
19 |
20 | [SecuritySafeCritical]
21 | protected override void OnRun(MessageContent content, CommandArgs args)
22 | {
23 | if (content.RoomName == null)
24 | throw new ArgumentNullException("content.RoomName");
25 |
26 | using (var client = ClientModel.Get())
27 | client.Chat.RemoveRoom(content.RoomName);
28 |
29 | ClientModel.Notifier.RoomClosed(new RoomClosedEventArgs(content.RoomName));
30 | }
31 |
32 | [Serializable]
33 | [BinType("ClientRoomClosed")]
34 | public class MessageContent
35 | {
36 | [BinField("r")]
37 | public string RoomName;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientRoomOpenedCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Client.P2P;
4 | using Engine.Exceptions;
5 | using Engine.Model.Client;
6 | using Engine.Model.Client.Entities;
7 | using Engine.Model.Common.Dto;
8 | using Engine.Model.Common.Entities;
9 | using ThirtyNineEighty.BinarySerializer;
10 |
11 | namespace Engine.Api.Client.Rooms
12 | {
13 | [SecurityCritical]
14 | class ClientRoomOpenedCommand :
15 | ClientCommand
16 | {
17 | public const long CommandId = (long)ClientCommandId.RoomOpened;
18 |
19 | public override long Id
20 | {
21 | [SecuritySafeCritical]
22 | get { return CommandId; }
23 | }
24 |
25 | [SecuritySafeCritical]
26 | protected override void OnRun(MessageContent content, CommandArgs args)
27 | {
28 | if (content.Room == null)
29 | throw new ArgumentNullException("content.Room");
30 |
31 | using (var client = ClientModel.Get())
32 | {
33 | Room room = null;
34 | if (content.Room.Type == RoomType.Chat)
35 | {
36 | var textRoom = new ClientRoom(content.Room);
37 | client.Chat.AddRoom(textRoom);
38 | room = textRoom;
39 | }
40 |
41 | if (content.Room.Type == RoomType.Voice)
42 | {
43 | var voiceRoom = new ClientVoiceRoom(content.Room);
44 | client.Chat.AddVoiceRoom(voiceRoom);
45 | room = voiceRoom;
46 | }
47 |
48 | if (room == null)
49 | throw new ModelException(ErrorCode.UnknownRoomType);
50 |
51 | AddUsers(client.Chat, content.Users);
52 |
53 | // Create P2P connections to users if need
54 | if (content.Room.ConnectTo != null)
55 | {
56 | foreach (var nick in content.Room.ConnectTo)
57 | ClientModel.Api.Perform(new ClientConnectToPeerAction(nick));
58 | }
59 |
60 | room.Enable();
61 | }
62 |
63 | ClientModel.Notifier.RoomOpened(new RoomOpenedEventArgs(content.Room.Name));
64 | }
65 |
66 | [Serializable]
67 | [BinType("ClientRoomOpened")]
68 | public class MessageContent
69 | {
70 | [BinField("r")]
71 | public RoomDto Room;
72 |
73 | [BinField("u")]
74 | public UserDto[] Users;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Rooms/ClientSetRoomAdminAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Server.Rooms;
2 | using Engine.Model.Client;
3 | using Engine.Model.Common.Entities;
4 | using System;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Client.Rooms
8 | {
9 | [Serializable]
10 | public class ClientSetRoomAdminAction : IAction
11 | {
12 | private readonly string _roomName;
13 | private readonly UserId _newAdmin;
14 |
15 | ///
16 | /// Change room admin.
17 | ///
18 | /// Room name.
19 | /// New room admin.
20 | [SecuritySafeCritical]
21 | public ClientSetRoomAdminAction(string roomName, UserId newAdmin)
22 | {
23 | if (string.IsNullOrEmpty(roomName))
24 | throw new ArgumentException(nameof(roomName));
25 |
26 | if (newAdmin == UserId.Empty)
27 | throw new ArgumentException(nameof(newAdmin));
28 |
29 | _roomName = roomName;
30 | _newAdmin = newAdmin;
31 | }
32 |
33 | [SecuritySafeCritical]
34 | public void Perform()
35 | {
36 | var sendingContent = new ServerSetRoomAdminCommand.MessageContent { RoomName = _roomName, NewAdmin = _newAdmin };
37 | ClientModel.Client.SendMessage(ServerSetRoomAdminCommand.CommandId, sendingContent);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Engine/Api/Client/Voice/ClientPlayVoiceCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Model.Client;
4 | using Engine.Model.Common.Entities;
5 | using ThirtyNineEighty.BinarySerializer;
6 |
7 | namespace Engine.Api.Client.Voice
8 | {
9 | [SecurityCritical]
10 | class ClientPlayVoiceCommand :
11 | ClientCommand
12 | {
13 | public static long CommandId = (long)ClientCommandId.PlayVoice;
14 |
15 | public override long Id
16 | {
17 | [SecuritySafeCritical]
18 | get { return CommandId; }
19 | }
20 |
21 | protected override bool IsPeerCommand
22 | {
23 | [SecuritySafeCritical]
24 | get { return true; }
25 | }
26 |
27 | [SecuritySafeCritical]
28 | protected override void OnRun(MessageContent content, CommandArgs args)
29 | {
30 | using (var client = ClientModel.Get())
31 | {
32 | var user = client.Chat.GetUser(args.ConnectionId);
33 | if (user.IsVoiceActive())
34 | ClientModel.Player.Enqueue(args.ConnectionId, content.Number, content.Pack);
35 | }
36 | }
37 |
38 | [Serializable]
39 | [BinType("ClientPlayVoice")]
40 | public class MessageContent
41 | {
42 | [BinField("p")]
43 | public SoundPack Pack;
44 |
45 | [BinField("n")]
46 | public long Number;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Engine/Api/IAction.cs:
--------------------------------------------------------------------------------
1 | namespace Engine.Api
2 | {
3 | public interface IAction
4 | {
5 | void Perform();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Engine/Api/IApi.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine.Api
4 | {
5 | public interface IApi : IDisposable
6 | {
7 | ///
8 | /// Name and version of Api.
9 | ///
10 | string Name { get; }
11 |
12 | ///
13 | /// Get the command by identifier.
14 | ///
15 | /// Command identifier.
16 | /// Command.
17 | ICommand GetCommand(long id);
18 |
19 | ///
20 | /// Perform the remote action.
21 | ///
22 | /// Action to perform.
23 | void Perform(IAction action);
24 | }
25 |
26 | public static class Api
27 | {
28 | ///
29 | /// Name and version of Api.
30 | ///
31 | public const string Name = "StandardAPI v5.1";
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Engine/Api/ICommand.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using Engine.Network;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Api
7 | {
8 | public interface ICommand
9 | {
10 | long Id { get; }
11 | void Run(CommandArgs args);
12 | }
13 |
14 | [Serializable]
15 | public sealed class CommandArgs : IDisposable
16 | {
17 | public UserId ConnectionId { get; private set; }
18 | public Unpacked Unpacked { get; private set; }
19 |
20 | public CommandArgs(UserId connectionId, Unpacked unpacked)
21 | {
22 | ConnectionId = connectionId;
23 | Unpacked = unpacked;
24 | }
25 |
26 | [SecuritySafeCritical]
27 | public void Dispose()
28 | {
29 | Unpacked.Dispose();
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Engine/Api/Server/Files/ServerAddFileToRoomCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Client.Files;
4 | using Engine.Api.Server.Messages;
5 | using Engine.Model.Common.Dto;
6 | using Engine.Model.Common.Entities;
7 | using Engine.Model.Server;
8 | using ThirtyNineEighty.BinarySerializer;
9 |
10 | namespace Engine.Api.Server.Files
11 | {
12 | [SecurityCritical]
13 | class ServerAddFileToRoomCommand :
14 | ServerCommand
15 | {
16 | public const long CommandId = (long)ServerCommandId.AddFileToRoom;
17 |
18 | public override long Id
19 | {
20 | [SecuritySafeCritical]
21 | get { return CommandId; }
22 | }
23 |
24 | [SecuritySafeCritical]
25 | protected override void OnRun(MessageContent content, CommandArgs args)
26 | {
27 | if (string.IsNullOrEmpty(content.RoomName))
28 | throw new ArgumentException(nameof(content.RoomName));
29 |
30 | if (content.File == null)
31 | throw new ArgumentNullException(nameof(content.File));
32 |
33 | using (var server = ServerModel.Get())
34 | {
35 | Room room;
36 | if (!TryGetRoom(server.Chat, content.RoomName, args.ConnectionId, out room))
37 | return;
38 |
39 | if (!room.IsUserExist(args.ConnectionId))
40 | {
41 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomAccessDenied));
42 | return;
43 | }
44 |
45 | if (!room.IsFileExist(content.File.Id))
46 | room.AddFile(new FileDescription(content.File));
47 |
48 | var sendingContent = new ClientFilePostedCommand.MessageContent
49 | {
50 | File = content.File,
51 | RoomName = content.RoomName
52 | };
53 |
54 | foreach (var user in room.Users)
55 | ServerModel.Server.SendMessage(user, ClientFilePostedCommand.CommandId, sendingContent);
56 | }
57 | }
58 |
59 | [Serializable]
60 | [BinType("ServerAddFileToRoom")]
61 | public class MessageContent
62 | {
63 | [BinField("r")]
64 | public string RoomName;
65 |
66 | [BinField("f")]
67 | public FileDescriptionDto File;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Messages/ServerRemoveMessagesAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Client.Messages;
2 | using Engine.Model.Common.Entities;
3 | using Engine.Model.Server;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Security;
7 |
8 | namespace Engine.Api.Server.Messages
9 | {
10 | [SecuritySafeCritical]
11 | public class ServerRemoveMessagesAction : IAction
12 | {
13 | private readonly UserId _userId;
14 | private readonly string _roomName;
15 | private readonly long[] _ids;
16 |
17 | [SecuritySafeCritical]
18 | public ServerRemoveMessagesAction(UserId userId, string roomName, IEnumerable ids)
19 | {
20 | _userId = userId;
21 | _roomName = roomName;
22 | _ids = ids as long[] ?? ids.ToArray();
23 | }
24 |
25 | [SecuritySafeCritical]
26 | public void Perform()
27 | {
28 | var messageContent = new ClientRemoveMessagesCommand.MessageContent { RoomName = _roomName, Ids = _ids };
29 | ServerModel.Server.SendMessage(_userId, ClientRemoveMessagesCommand.CommandId, messageContent);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Messages/ServerSendSystemMessageAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Client.Messages;
2 | using Engine.Model.Common.Entities;
3 | using Engine.Model.Server;
4 | using System;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Server.Messages
8 | {
9 | [Serializable]
10 | public class ServerSendSystemMessageAction : IAction
11 | {
12 | private readonly UserId _userId;
13 | private readonly SystemMessageId _message;
14 | private readonly string[] _formatParams;
15 |
16 | ///
17 | /// Send system message to user.
18 | ///
19 | /// Reciver of system message.
20 | /// System message id.
21 | /// Format params for message.
22 | [SecuritySafeCritical]
23 | public ServerSendSystemMessageAction(UserId userId, SystemMessageId message, params string[] formatParams)
24 | {
25 | _userId = userId;
26 | _message = message;
27 | _formatParams = formatParams;
28 | }
29 |
30 | [SecuritySafeCritical]
31 | public void Perform()
32 | {
33 | var sendingContent = new ClientOutSystemMessageCommand.MessageContent { Message = _message, FormatParams = _formatParams };
34 | ServerModel.Server.SendMessage(_userId, ClientOutSystemMessageCommand.CommandId, sendingContent);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Others/ServerEmptyCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Security;
2 |
3 | namespace Engine.Api.Server.Others
4 | {
5 | [SecurityCritical]
6 | class ServerEmptyCommand : ServerCommand
7 | {
8 | public const long CommandId = (long)ServerCommandId.Empty;
9 | public static readonly ServerEmptyCommand Empty = new ServerEmptyCommand();
10 |
11 | public override long Id
12 | {
13 | [SecuritySafeCritical]
14 | get { return CommandId; }
15 | }
16 |
17 | [SecurityCritical]
18 | protected ServerEmptyCommand()
19 | {
20 |
21 | }
22 |
23 | [SecuritySafeCritical]
24 | protected override void OnRun(CommandArgs args)
25 | {
26 |
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Others/ServerPingRequestCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Security;
2 | using Engine.Api.Client.Others;
3 | using Engine.Model.Server;
4 |
5 | namespace Engine.Api.Server.Others
6 | {
7 | [SecurityCritical]
8 | class ServerPingRequestCommand : ServerCommand
9 | {
10 | public const long CommandId = (long)ServerCommandId.PingRequest;
11 |
12 | public override long Id
13 | {
14 | [SecuritySafeCritical]
15 | get { return CommandId; }
16 | }
17 |
18 | [SecuritySafeCritical]
19 | protected override void OnRun(CommandArgs args)
20 | {
21 | ServerModel.Server.SendMessage(args.ConnectionId, ClientPingResponseCommand.CommandId, true);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Engine/Api/Server/P2P/ServerIntroduceConnectionsAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Client.P2P;
2 | using Engine.Model.Common.Dto;
3 | using Engine.Model.Common.Entities;
4 | using Engine.Model.Server;
5 | using System;
6 | using System.Net;
7 | using System.Security;
8 |
9 | namespace Engine.Api.Server.P2P
10 | {
11 | [Serializable]
12 | public class ServerIntroduceConnectionsAction : IAction
13 | {
14 | private readonly UserId _senderId;
15 | private readonly IPEndPoint _senderPoint;
16 | private readonly UserId _requestId;
17 | private readonly IPEndPoint _requestPoint;
18 |
19 | ///
20 | /// Connect users directly.
21 | ///
22 | /// User who request direct connection.
23 | /// Address of user who request direct connection.
24 | /// Requested user.
25 | /// Address of requested user.
26 | [SecuritySafeCritical]
27 | public ServerIntroduceConnectionsAction(UserId senderId, IPEndPoint senderPoint, UserId requestId, IPEndPoint requestPoint)
28 | {
29 | _senderId = senderId;
30 | _senderPoint = senderPoint;
31 | _requestId = requestId;
32 | _requestPoint = requestPoint;
33 | }
34 |
35 | [SecuritySafeCritical]
36 | public void Perform()
37 | {
38 | using (var server = ServerModel.Get())
39 | {
40 | var senderUser = server.Chat.GetUser(_senderId);
41 | var certiticate = ServerModel.Server.GetCertificate(_senderId);
42 | var content = new ClientWaitPeerConnectionCommand.MessageContent
43 | {
44 | RequestIpAddress = _requestPoint.Address.GetAddressBytes(),
45 | RequestPort = _requestPoint.Port,
46 | SenderIpAddress = _senderPoint.Address.GetAddressBytes(),
47 | SenderPort = _senderPoint.Port,
48 | RemoteInfo = new UserDto(senderUser, certiticate.RawData),
49 | };
50 |
51 | ServerModel.Server.SendMessage(_requestId, ClientWaitPeerConnectionCommand.CommandId, content);
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Engine/Api/Server/P2P/ServerP2PConnectRequestCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Server.Messages;
4 | using Engine.Model.Common.Entities;
5 | using Engine.Model.Server;
6 | using ThirtyNineEighty.BinarySerializer;
7 |
8 | namespace Engine.Api.Server.P2P
9 | {
10 | [SecurityCritical]
11 | class ServerP2PConnectRequestCommand :
12 | ServerCommand
13 | {
14 | public const long CommandId = (long)ServerCommandId.P2PConnectRequest;
15 |
16 | public override long Id
17 | {
18 | [SecuritySafeCritical]
19 | get { return CommandId; }
20 | }
21 |
22 | [SecuritySafeCritical]
23 | protected override void OnRun(MessageContent content, CommandArgs args)
24 | {
25 | if (content.UserId == UserId.Empty)
26 | throw new ArgumentException("content.Nick");
27 |
28 | if (!ServerModel.Server.ContainsConnection(content.UserId))
29 | {
30 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.P2PUserNotExist));
31 | return;
32 | }
33 |
34 | ServerModel.Server.P2PService.Introduce(args.ConnectionId, content.UserId);
35 | }
36 |
37 | [Serializable]
38 | [BinType("ServerP2PConnectRequest")]
39 | public class MessageContent
40 | {
41 | [BinField("n")]
42 | public UserId UserId;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Engine/Api/Server/P2P/ServerP2PReadyAcceptCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Client.P2P;
4 | using Engine.Api.Server.Messages;
5 | using Engine.Model.Common.Dto;
6 | using Engine.Model.Common.Entities;
7 | using Engine.Model.Server;
8 | using ThirtyNineEighty.BinarySerializer;
9 |
10 | namespace Engine.Api.Server.P2P
11 | {
12 | [SecurityCritical]
13 | class ServerP2PReadyAcceptCommand :
14 | ServerCommand
15 | {
16 | public const long CommandId = (long)ServerCommandId.P2PReadyAccept;
17 |
18 | public override long Id
19 | {
20 | [SecuritySafeCritical]
21 | get { return CommandId; }
22 | }
23 |
24 | [SecuritySafeCritical]
25 | protected override void OnRun(MessageContent content, CommandArgs args)
26 | {
27 | if (content.RemoteInfo == null)
28 | throw new ArgumentNullException("content.RemoteInfo");
29 |
30 | if (!ServerModel.Server.ContainsConnection(content.ReceiverId))
31 | {
32 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.P2PUserNotExist));
33 | return;
34 | }
35 |
36 | var connectContent = new ClientConnectToPeerCommand.MessageContent
37 | {
38 | Port = content.PeerPort,
39 | IPAddress = content.PeerIPAddress,
40 | RemoteInfo = content.RemoteInfo
41 | };
42 |
43 | ServerModel.Server.SendMessage(content.ReceiverId, ClientConnectToPeerCommand.CommandId, connectContent);
44 | }
45 |
46 | [Serializable]
47 | [BinType("ServerP2PReadyAccept")]
48 | public class MessageContent
49 | {
50 | [BinField("r")]
51 | public UserId ReceiverId;
52 |
53 | [BinField("p")]
54 | public int PeerPort;
55 |
56 | [BinField("a")]
57 | public byte[] PeerIPAddress;
58 |
59 | [BinField("u")]
60 | public UserDto RemoteInfo;
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Engine/Api/Server/P2P/ServerSendP2PConnectRequestAction.cs:
--------------------------------------------------------------------------------
1 | using Engine.Api.Client.P2P;
2 | using Engine.Model.Common.Entities;
3 | using Engine.Model.Server;
4 | using System;
5 | using System.Security;
6 |
7 | namespace Engine.Api.Server.P2P
8 | {
9 | [Serializable]
10 | public class ServerSendP2PConnectRequestAction : IAction
11 | {
12 | private readonly UserId _userId;
13 | private readonly int _servicePort;
14 |
15 | ///
16 | /// Send request to user for connection to P2PService.
17 | ///
18 | /// User who recive connection request.
19 | /// P2PService port.
20 | [SecuritySafeCritical]
21 | public ServerSendP2PConnectRequestAction(UserId userId, int servicePort)
22 | {
23 | _userId = userId;
24 | _servicePort = servicePort;
25 | }
26 |
27 | [SecuritySafeCritical]
28 | public void Perform()
29 | {
30 | var sendingContent = new ClientConnectToP2PServiceCommand.MessageContent { Port = _servicePort };
31 | ServerModel.Server.SendMessage(_userId, ClientConnectToP2PServiceCommand.CommandId, sendingContent);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Registrations/ServerUnregisterCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Security;
2 | using Engine.Model.Server;
3 |
4 | namespace Engine.Api.Server.Registrations
5 | {
6 | [SecurityCritical]
7 | class ServerUnregisterCommand : ServerCommand
8 | {
9 | public const long CommandId = (long)ServerCommandId.Unregister;
10 |
11 | public override long Id
12 | {
13 | [SecuritySafeCritical]
14 | get { return CommandId; }
15 | }
16 |
17 | [SecuritySafeCritical]
18 | protected override void OnRun(CommandArgs args)
19 | {
20 | ServerModel.Api.Perform(new ServerRemoveUserAction(args.ConnectionId));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Rooms/ServerCreateRoomCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Client.Rooms;
4 | using Engine.Api.Server.Messages;
5 | using Engine.Model.Common.Entities;
6 | using Engine.Model.Server;
7 | using Engine.Model.Server.Entities;
8 | using ThirtyNineEighty.BinarySerializer;
9 |
10 | namespace Engine.Api.Server.Rooms
11 | {
12 | [SecurityCritical]
13 | class ServerCreateRoomCommand :
14 | ServerCommand
15 | {
16 | public const long CommandId = (long)ServerCommandId.CreateRoom;
17 |
18 | public override long Id
19 | {
20 | [SecuritySafeCritical]
21 | get { return CommandId; }
22 | }
23 |
24 | [SecuritySafeCritical]
25 | protected override void OnRun(MessageContent content, CommandArgs args)
26 | {
27 | if (string.IsNullOrEmpty(content.RoomName))
28 | throw new ArgumentNullException("content.RoomName");
29 |
30 | using(var server = ServerModel.Get())
31 | {
32 | if (server.Chat.IsRoomExist(content.RoomName))
33 | {
34 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomAlreadyExist));
35 | return;
36 | }
37 |
38 | Room room = null;
39 | if (content.Type == RoomType.Chat)
40 | {
41 | var textRoom = new ServerRoom(args.ConnectionId, content.RoomName);
42 | server.Chat.AddRoom(textRoom);
43 | room = textRoom;
44 | }
45 |
46 | if (content.Type == RoomType.Voice)
47 | {
48 | var voiceRoom = new ServerVoiceRoom(args.ConnectionId, content.RoomName);
49 | server.Chat.AddVoiceRoom(voiceRoom);
50 | room = voiceRoom;
51 | }
52 |
53 | if (room == null)
54 | throw new ArgumentException("content.RoomType");
55 |
56 | var sendingContent = new ClientRoomOpenedCommand.MessageContent
57 | {
58 | Room = room.ToDto(args.ConnectionId),
59 | Users = server.Chat.GetRoomUserDtos(room.Name)
60 | };
61 |
62 | ServerModel.Server.SendMessage(args.ConnectionId, ClientRoomOpenedCommand.CommandId, sendingContent);
63 | }
64 | }
65 |
66 | [Serializable]
67 | [BinType("ServerCreateRoom")]
68 | public class MessageContent
69 | {
70 | [BinField("r")]
71 | public string RoomName;
72 |
73 | [BinField("t")]
74 | public RoomType Type;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Rooms/ServerDeleteRoomCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Client.Rooms;
4 | using Engine.Api.Server.Messages;
5 | using Engine.Model.Common.Entities;
6 | using Engine.Model.Server;
7 | using Engine.Model.Server.Entities;
8 | using ThirtyNineEighty.BinarySerializer;
9 |
10 | namespace Engine.Api.Server.Rooms
11 | {
12 | [SecurityCritical]
13 | class ServerDeleteRoomCommand :
14 | ServerCommand
15 | {
16 | public const long CommandId = (long)ServerCommandId.DeleteRoom;
17 |
18 | public override long Id
19 | {
20 | [SecuritySafeCritical]
21 | get { return CommandId; }
22 | }
23 |
24 | [SecuritySafeCritical]
25 | protected override void OnRun(MessageContent content, CommandArgs args)
26 | {
27 | if (string.IsNullOrEmpty(content.RoomName))
28 | throw new ArgumentException("content.RoomName");
29 |
30 | if (content.RoomName == ServerChat.MainRoomName)
31 | {
32 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomAccessDenied));
33 | return;
34 | }
35 |
36 | using (var server = ServerModel.Get())
37 | {
38 | Room deletingRoom;
39 | if (!TryGetRoom(server.Chat, content.RoomName, args.ConnectionId, out deletingRoom))
40 | return;
41 |
42 | if (deletingRoom.Admin != args.ConnectionId)
43 | {
44 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomAccessDenied));
45 | return;
46 | }
47 |
48 | server.Chat.RemoveRoom(content.RoomName);
49 |
50 | var sendingContent = new ClientRoomClosedCommand.MessageContent { RoomName = deletingRoom.Name };
51 | foreach (var user in deletingRoom.Users)
52 | ServerModel.Server.SendMessage(user, ClientRoomClosedCommand.CommandId, sendingContent);
53 | }
54 | }
55 |
56 | [Serializable]
57 | [BinType("ServerDeleteRoom")]
58 | public class MessageContent
59 | {
60 | [BinField("r")]
61 | public string RoomName;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Rooms/ServerRefreshRoomCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Client.Rooms;
4 | using Engine.Api.Server.Messages;
5 | using Engine.Model.Common.Entities;
6 | using Engine.Model.Server;
7 | using ThirtyNineEighty.BinarySerializer;
8 |
9 | namespace Engine.Api.Server.Rooms
10 | {
11 | [SecurityCritical]
12 | class ServerRefreshRoomCommand :
13 | ServerCommand
14 | {
15 | public const long CommandId = (long)ServerCommandId.RefreshRoom;
16 |
17 | public override long Id
18 | {
19 | [SecuritySafeCritical]
20 | get { return CommandId; }
21 | }
22 |
23 | [SecuritySafeCritical]
24 | protected override void OnRun(MessageContent content, CommandArgs args)
25 | {
26 | if (string.IsNullOrEmpty(content.RoomName))
27 | throw new ArgumentException("content.RoomName");
28 |
29 | using (var server = ServerModel.Get())
30 | {
31 | Room room;
32 | if (!TryGetRoom(server.Chat, content.RoomName, args.ConnectionId, out room))
33 | return;
34 |
35 | if (!room.IsUserExist(args.ConnectionId))
36 | {
37 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomAccessDenied));
38 | return;
39 | }
40 |
41 | var roomRefreshedContent = new ClientRoomRefreshedCommand.MessageContent
42 | {
43 | Room = room.ToDto(args.ConnectionId),
44 | Users = server.Chat.GetRoomUserDtos(room.Name)
45 | };
46 |
47 | ServerModel.Server.SendMessage(args.ConnectionId, ClientRoomRefreshedCommand.CommandId, roomRefreshedContent);
48 | }
49 | }
50 |
51 | [Serializable]
52 | [BinType("ServerRefreshRoom")]
53 | public class MessageContent
54 | {
55 | [BinField("r")]
56 | public string RoomName;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Engine/Api/Server/Rooms/ServerSetRoomAdminCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Engine.Api.Server.Messages;
4 | using Engine.Model.Common.Entities;
5 | using Engine.Model.Server;
6 | using Engine.Model.Server.Entities;
7 | using ThirtyNineEighty.BinarySerializer;
8 |
9 | namespace Engine.Api.Server.Rooms
10 | {
11 | [SecurityCritical]
12 | class ServerSetRoomAdminCommand :
13 | ServerCommand
14 | {
15 | public const long CommandId = (long)ServerCommandId.SetRoomAdmin;
16 |
17 | public override long Id
18 | {
19 | [SecuritySafeCritical]
20 | get { return CommandId; }
21 | }
22 |
23 | [SecuritySafeCritical]
24 | protected override void OnRun(MessageContent content, CommandArgs args)
25 | {
26 | if (string.IsNullOrEmpty(content.RoomName))
27 | throw new ArgumentException("content.RoomName");
28 |
29 | if (content.RoomName == ServerChat.MainRoomName)
30 | {
31 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomAccessDenied));
32 | return;
33 | }
34 |
35 | using (var server = ServerModel.Get())
36 | {
37 | Room room;
38 | if (!TryGetRoom(server.Chat, content.RoomName, args.ConnectionId, out room))
39 | return;
40 |
41 | if (room.Admin != args.ConnectionId)
42 | {
43 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomAccessDenied));
44 | return;
45 | }
46 |
47 | if (!room.IsUserExist(content.NewAdmin))
48 | {
49 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(args.ConnectionId, SystemMessageId.RoomUserNotExist));
50 | return;
51 | }
52 |
53 | room.Admin = content.NewAdmin;
54 | ServerModel.Api.Perform(new ServerSendSystemMessageAction(content.NewAdmin, SystemMessageId.RoomAdminChanged, room.Name));
55 | }
56 | }
57 |
58 | [Serializable]
59 | [BinType("ServerSetRoomAdmin")]
60 | public class MessageContent
61 | {
62 | [BinField("r")]
63 | public string RoomName;
64 |
65 | [BinField("a")]
66 | public UserId NewAdmin;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Engine/Api/Server/ServerCommandId.cs:
--------------------------------------------------------------------------------
1 | namespace Engine.Api.Server
2 | {
3 | // TODO: rus
4 | //Команды для сервера: (формат сообщений XX XX Serialized(this.MessageContent))
5 | //Расшифровка XX XX:
6 | //8 00 00: Запрос регистрации (в главной комнате)
7 | //8 00 01: Запрос выхода (из всех комнат)
8 |
9 | //8 00 10: Отправка сообщения всем клиентам в комнате
10 | //8 00 11: Отправка личного сообщения конкретному юзеру
11 |
12 | //8 00 20: Запрос открытого пароля пользователя
13 |
14 | //8 00 30: Создать комнату
15 | //8 00 31: Удалить комнату
16 | //8 00 32: Пригласить пользователей в комнату
17 | //8 00 33: Кикнуть пользователей из комнаты
18 | //8 00 34: Выйти из комнаты
19 | //8 00 35: Запрос обновления комнаты
20 | //8 00 36: Сделать пользователя администратором комнаты
21 |
22 | //8 00 40: Пинг запрос
23 |
24 | //8 00 50: Добавить файл на раздачу комнаты
25 | //8 00 51: Удалить файл с раздачи комнаты
26 |
27 | //8 00 60: Запрос прямого соединения
28 | //8 00 61: Ответ, говорящий о готовности принять входное содеинение
29 |
30 | //8 00 70: Text admin command
31 |
32 | //8 7F FF: Пустая команда
33 |
34 | enum ServerCommandId : long
35 | {
36 | Register = 0x80000,
37 | Unregister = 0x80001,
38 |
39 | SendRoomMessage = 0x80010,
40 | SendPrivateMessage = 0x80011,
41 |
42 | GetUserOpenKeyRequest = 0x80020,
43 |
44 | CreateRoom = 0x80030,
45 | DeleteRoom = 0x80031,
46 | InvateUsers = 0x80032,
47 | KickUsers = 0x80033,
48 | ExitFromRoom = 0x80034,
49 | RefreshRoom = 0x80035,
50 | SetRoomAdmin = 0x80036,
51 |
52 | PingRequest = 0x80040,
53 |
54 | AddFileToRoom = 0x80050,
55 | RemoveFileFromRoom = 0x80051,
56 |
57 | P2PConnectRequest = 0x80060,
58 | P2PReadyAccept = 0x80061,
59 |
60 | Admin = 0x80070,
61 |
62 | Empty = 0x87FFF
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Engine/Audio/IPlayer.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Engine.Audio
6 | {
7 | // TODO: rus
8 | public interface IPlayer : IDisposable
9 | {
10 | ///
11 | /// Устанавливает устройство воспроизводящее звук.
12 | ///
13 | /// Имя устройства.
14 | void SetOptions(string deviceName);
15 |
16 | ///
17 | /// Ставит в очередь на воспроизведение массив звуковых данных, для пользователя.
18 | ///
19 | /// Id пользователя.
20 | ///
21 | /// Номер пакета.
22 | /// Если меньше чем текущий воспроизведенный, пакет воспроизведен не будет.
23 | ///
24 | /// Пакет с данными о записи.
25 | void Enqueue(UserId id, long packNumber, SoundPack pack);
26 |
27 | ///
28 | /// Оставноить воспроизведение для пользователя.
29 | ///
30 | /// Id Пользователя.
31 | void Stop(UserId id);
32 |
33 | ///
34 | /// Остановить воспроизведение.
35 | ///
36 | void Stop();
37 |
38 | ///
39 | /// Возвращает заначение говоряеще о том инциализирован ли класс.
40 | ///
41 | bool IsInited { get; }
42 |
43 | ///
44 | /// Возвращает список утросйств воспроизводящих звук.
45 | ///
46 | IList Devices { get; }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Engine/Audio/IRecorder.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace Engine.Audio
6 | {
7 | public interface IRecorder : IDisposable
8 | {
9 | ///
10 | /// Происходит при заполнении буффера.
11 | ///
12 | event EventHandler Recorded;
13 |
14 | ///
15 | /// Устанавливает настройки качества записи. И устройство записывающее звук.
16 | ///
17 | /// Имя устройства.
18 | /// Количество записи.
19 | void SetOptions(string deviceName, AudioQuality quality);
20 |
21 | ///
22 | /// Запускает запись с микрофона.
23 | ///
24 | void Start();
25 |
26 | ///
27 | /// Останавливает запись с микрофона.
28 | ///
29 | void Stop();
30 |
31 | ///
32 | /// Возвращает заначение говоряеще о том инциализирован ли класс.
33 | ///
34 | bool IsInited { get; }
35 |
36 | ///
37 | /// Возвращает список утросйств записывающих звук.
38 | ///
39 | IList Devices { get; }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Engine/EngineStrongName.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aoaydin/TCPChat/245d8caadd3dc7884bae06afc00b03fa81905e73/Engine/EngineStrongName.snk
--------------------------------------------------------------------------------
/Engine/EventArgs/AsyncErrorEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine
4 | {
5 | [Serializable]
6 | public class AsyncErrorEventArgs : EventArgs
7 | {
8 | public Exception Error { get; private set; }
9 |
10 | public AsyncErrorEventArgs(Exception e)
11 | {
12 | Error = e;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Engine/EventArgs/ConnectEventArgs.cs:
--------------------------------------------------------------------------------
1 | using Engine.Network;
2 | using System;
3 |
4 | namespace Engine
5 | {
6 | [Serializable]
7 | public class ConnectEventArgs : EventArgs
8 | {
9 | public Exception Error { get; private set; }
10 |
11 | public ConnectEventArgs()
12 | {
13 | }
14 |
15 | public ConnectEventArgs(Exception e)
16 | {
17 | Error = e;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Engine/EventArgs/ConnectionEventArgs.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 |
4 | namespace Engine
5 | {
6 | [Serializable]
7 | public class ConnectionEventArgs : EventArgs
8 | {
9 | public UserId Id { get; private set; }
10 |
11 | public ConnectionEventArgs(UserId id)
12 | {
13 | Id = id;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Engine/EventArgs/FileDownloadEventArgs.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 |
4 | namespace Engine
5 | {
6 | [Serializable]
7 | public class FileDownloadEventArgs : EventArgs
8 | {
9 | public string RoomName { get; private set; }
10 | public FileId FileId { get; private set; }
11 |
12 | public int Progress { get; private set; }
13 |
14 | public FileDownloadEventArgs(string roomName, FileId fileId, int progress)
15 | {
16 | RoomName = roomName;
17 | FileId = fileId;
18 | Progress = progress;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Engine/EventArgs/PackageReceivedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using Engine.Network;
2 | using System;
3 |
4 | namespace Engine
5 | {
6 | [Serializable]
7 | public class PackageReceivedEventArgs : EventArgs
8 | {
9 | public Unpacked Unpacked { get; private set; }
10 | public Exception Exception { get; private set; }
11 |
12 | public PackageReceivedEventArgs(Unpacked unpacked)
13 | {
14 | Unpacked = unpacked;
15 | }
16 |
17 | public PackageReceivedEventArgs(Exception e)
18 | {
19 | Exception = e;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Engine/EventArgs/PackageSendedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine
4 | {
5 | [Serializable]
6 | public class PackageSendedEventArgs : EventArgs
7 | {
8 | public int Size { get; private set; }
9 | public Exception Exception { get; private set; }
10 |
11 | public PackageSendedEventArgs(int size)
12 | {
13 | Size = size;
14 | }
15 |
16 | public PackageSendedEventArgs(Exception e)
17 | {
18 | Exception = e;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Engine/EventArgs/PluginEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine
4 | {
5 | [Serializable]
6 | public class PluginEventArgs : EventArgs
7 | {
8 | public string PluginName { get; private set; }
9 |
10 | public PluginEventArgs(string pluginName)
11 | {
12 | PluginName = pluginName;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Engine/EventArgs/ReceiveMessageEventArgs.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 |
4 | namespace Engine
5 | {
6 | [Serializable]
7 | public class ReceiveMessageEventArgs : EventArgs
8 | {
9 | public long MessageId { get; set; }
10 | public MessageType Type { get; set; }
11 | public DateTime Time { get; set; }
12 |
13 | public UserId Sender { get; set; }
14 | public string RoomName { get; set; }
15 |
16 | public string Message { get; set; }
17 |
18 | public SystemMessageId SystemMessage { get; set; }
19 | public string[] SystemMessageFormat { get; set; }
20 |
21 | public FileId FileId { get; set; }
22 | }
23 |
24 | public enum MessageType
25 | {
26 | Common,
27 | Private,
28 | System,
29 | File
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Engine/EventArgs/RecordedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine
4 | {
5 | [Serializable]
6 | public class RecordedEventArgs : EventArgs
7 | {
8 | public byte[] Data { get; private set; }
9 | public int DataSize { get; private set; }
10 | public int Channels { get; private set; }
11 | public int BitPerChannel { get; private set; }
12 | public int Frequency { get; private set; }
13 |
14 | public RecordedEventArgs(byte[] data, int availableData, int channels, int bits, int frequency)
15 | {
16 | Data = data;
17 | DataSize = availableData * channels * (bits / 8);
18 | Channels = channels;
19 | BitPerChannel = bits;
20 | Frequency = frequency;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Engine/EventArgs/RegistrationEventArgs.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 |
4 | namespace Engine
5 | {
6 | [Serializable]
7 | public class RegistrationEventArgs : EventArgs
8 | {
9 | public bool Registered { get; set; }
10 | public SystemMessageId Message { get; set; }
11 |
12 | public RegistrationEventArgs(bool registered, SystemMessageId message)
13 | {
14 | Registered = registered;
15 | Message = message;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Engine/EventArgs/RoomClosedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine
4 | {
5 | [Serializable]
6 | public class RoomClosedEventArgs : EventArgs
7 | {
8 | public string RoomName { get; private set; }
9 |
10 | public RoomClosedEventArgs(string roomName)
11 | {
12 | RoomName = roomName;
13 | }
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/Engine/EventArgs/RoomOpenedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine
4 | {
5 | [Serializable]
6 | public class RoomOpenedEventArgs : EventArgs
7 | {
8 | public string RoomName { get; private set; }
9 |
10 | public RoomOpenedEventArgs(string roomName)
11 | {
12 | RoomName = roomName;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Engine/EventArgs/RoomRefreshedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Engine
5 | {
6 | [Serializable]
7 | public class RoomRefreshedEventArgs : EventArgs
8 | {
9 | public string RoomName { get; private set; }
10 | public HashSet AddedMessages { get; private set; }
11 | public HashSet RemovedMessages { get; private set; }
12 |
13 | public RoomRefreshedEventArgs(string roomName, HashSet addedMessages, HashSet removedMessages)
14 | {
15 | RoomName = roomName;
16 | AddedMessages = addedMessages;
17 | RemovedMessages = removedMessages;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Engine/EventArgs/RoomUsersEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine
4 | {
5 | public class RoomUsersEventArgs : EventArgs
6 | {
7 | public string Nick { get; private set; }
8 | public bool Removed { get; private set; }
9 |
10 | public RoomUsersEventArgs(string nick, bool removed)
11 | {
12 | Nick = nick;
13 | Removed = removed;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Engine/EventArgs/TrustedCertificatesEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography.X509Certificates;
3 |
4 | namespace Engine
5 | {
6 | public class TrustedCertificatesEventArgs : EventArgs
7 | {
8 | public X509Certificate2 Certificate { get; private set; }
9 | public bool Removed { get; private set; }
10 |
11 | public TrustedCertificatesEventArgs(X509Certificate2 cert, bool removed)
12 | {
13 | Certificate = cert;
14 | Removed = removed;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Engine/Exceptions/ErrorCode.cs:
--------------------------------------------------------------------------------
1 | namespace Engine.Exceptions
2 | {
3 | public enum ErrorCode
4 | {
5 | ApiNotSupported = 1,
6 | FileAlreadyDownloading = 2,
7 | FreePortDontFound = 3,
8 | LargeReceivedData = 4,
9 | CantDownloadOwnFile = 5,
10 |
11 | AudioNotEnabled = 100,
12 |
13 | PluginError = 200,
14 |
15 | RoomNotFound = 300,
16 | FileInRoomNotFound = 301,
17 | UnknownRoomType = 302,
18 |
19 | WrongContentType = 1000,
20 | IllegalInvoker = 1001
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Engine/Exceptions/ModelException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine.Exceptions
4 | {
5 | [Serializable]
6 | public class ModelException : Exception
7 | {
8 | public ErrorCode Code { get; private set; }
9 | public object State { get; private set; }
10 |
11 | public ModelException(ErrorCode code, string message, Exception inner, object state = null)
12 | : base(message, inner)
13 | {
14 | Code = code;
15 | State = state;
16 | }
17 |
18 | public ModelException(ErrorCode code, string message, object state = null)
19 | : base(message)
20 | {
21 | Code = code;
22 | State = state;
23 | }
24 |
25 | public ModelException(ErrorCode code, object state = null)
26 | : this(code, code.ToString(), state)
27 | {
28 |
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Engine/Helpers/EventDispatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Engine.Helpers
4 | {
5 | internal static class EventDispatcher
6 | {
7 | public static void BeginDispatch(this EventHandler handler, object sender, T args, Action onEnd)
8 | where T: EventArgs
9 | {
10 | if (handler != null)
11 | ArgsDispatcher.BeginDispatch(handler, sender, args, onEnd);
12 | else
13 | {
14 | if (onEnd != null)
15 | onEnd(null);
16 | }
17 | }
18 |
19 | private static class ArgsDispatcher
20 | where T : EventArgs
21 | {
22 | private class State
23 | {
24 | public readonly EventHandler Invoked;
25 | public readonly Action OnEnd;
26 |
27 | public State(EventHandler invoked, Action onEnd)
28 | {
29 | Invoked = invoked;
30 | OnEnd = onEnd;
31 | }
32 | }
33 |
34 | public static void BeginDispatch(EventHandler handler, object sender, T args, Action onEnd)
35 | {
36 | handler.BeginInvoke(sender, args, EndDispatch, new State(handler, onEnd));
37 | }
38 |
39 | private static void EndDispatch(IAsyncResult result)
40 | {
41 | Exception exception = null;
42 | var state = (State)result.AsyncState;
43 | try
44 | {
45 | state.Invoked.EndInvoke(result);
46 | }
47 | catch (Exception e)
48 | {
49 | exception = e;
50 | }
51 | finally
52 | {
53 | if (state.OnEnd != null)
54 | state.OnEnd(exception);
55 | }
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Engine/Helpers/Serializer.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Security;
3 | using System.Security.Permissions;
4 | using ThirtyNineEighty.BinarySerializer;
5 |
6 | namespace Engine.Helpers
7 | {
8 | public static class Serializer
9 | {
10 | [SecuritySafeCritical]
11 | [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
12 | public static byte[] Serialize(T obj)
13 | {
14 | using (MemoryStream stream = new MemoryStream())
15 | {
16 | BinSerializer.Serialize(stream, obj);
17 | return stream.ToArray();
18 | }
19 | }
20 |
21 | [SecuritySafeCritical]
22 | [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
23 | public static void Serialize(Stream stream, T obj)
24 | {
25 | BinSerializer.Serialize(stream, obj);
26 | }
27 |
28 | [SecuritySafeCritical]
29 | [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
30 | public static T Deserialize(byte[] message)
31 | {
32 | using (MemoryStream stream = new MemoryStream(message))
33 | return BinSerializer.Deserialize(stream);
34 | }
35 |
36 | [SecuritySafeCritical]
37 | [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
38 | public static T Deserialize(Stream stream)
39 | {
40 | return BinSerializer.Deserialize(stream);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Engine/Helpers/TryLock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace Engine.Helpers
5 | {
6 | public struct TryLock : IDisposable
7 | {
8 | private volatile bool _lockTaken;
9 | private readonly object _syncObject;
10 |
11 | public TryLock(object obj, int timeout = 10000)
12 | {
13 | _syncObject = obj;
14 | _lockTaken = Monitor.TryEnter(_syncObject, timeout);
15 | if (!_lockTaken)
16 | throw new InvalidOperationException("TryEnterLock timeout");
17 | }
18 |
19 | public void Dispose()
20 | {
21 | if (_lockTaken)
22 | Monitor.Exit(_syncObject);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Engine/Model/Client/ClientCertificatesStorage.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography.X509Certificates;
2 | using Engine.Helpers;
3 | using Engine.Model.Common;
4 |
5 | namespace Engine.Model.Client
6 | {
7 | public class ClientCertificatesStorage : CertificatesStorage
8 | {
9 | private readonly IClientNotifier _notifier;
10 |
11 | public ClientCertificatesStorage(string path, IClientNotifier notifier, Logger logger)
12 | : base(path, logger)
13 | {
14 | _notifier = notifier;
15 | }
16 |
17 | protected override void OnAdded(X509Certificate2 certificate)
18 | {
19 | base.OnAdded(certificate);
20 | _notifier.TrustedCertificatesChanged(new TrustedCertificatesEventArgs(certificate, false));
21 | }
22 |
23 | protected override void OnRemoved(X509Certificate2 certificate)
24 | {
25 | base.OnRemoved(certificate);
26 | _notifier.TrustedCertificatesChanged(new TrustedCertificatesEventArgs(certificate, true));
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Engine/Model/Client/ClientGuard.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Client.Entities;
2 | using System.Security;
3 |
4 | namespace Engine.Model.Client
5 | {
6 | public class ClientGuard : Guard
7 | {
8 | [SecurityCritical]
9 | public ClientGuard(ClientChat chat)
10 | : base(chat)
11 | {
12 |
13 | }
14 |
15 | public ClientChat Chat
16 | {
17 | get { return _obj; }
18 | }
19 |
20 | public static ClientChat CurrentChat
21 | {
22 | [SecuritySafeCritical]
23 | get { return ((ClientGuard)_current).Chat; }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Engine/Model/Client/ClientInitializer.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Security.Cryptography.X509Certificates;
3 |
4 | namespace Engine.Model.Client
5 | {
6 | public class ClientInitializer
7 | {
8 | public string Nick { get; set; }
9 | public Color NickColor { get; set; }
10 | public X509Certificate2 Certificate { get; set; }
11 | public string TrustedCertificatesPath { get; set; }
12 |
13 | public string PluginsPath { get; set; }
14 | public string[] ExcludedPlugins { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Engine/Model/Client/Entities/ClientRoom.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Dto;
2 | using Engine.Model.Common.Entities;
3 | using System;
4 | using System.Security;
5 |
6 | namespace Engine.Model.Client.Entities
7 | {
8 | [Serializable]
9 | public class ClientRoom : Room
10 | {
11 | [SecuritySafeCritical]
12 | public ClientRoom(RoomDto dto)
13 | : base(dto.Admin, dto.Name)
14 | {
15 | foreach (var nick in dto.Users)
16 | _users.Add(nick);
17 |
18 | foreach (var file in dto.Files)
19 | _files.Add(file.Id, new FileDescription(file));
20 |
21 | foreach (var message in dto.Messages)
22 | _messages.Add(message.Id, new Message(message));
23 | }
24 |
25 | #region files
26 | [SecuritySafeCritical]
27 | public override bool RemoveFile(FileId fileId)
28 | {
29 | var result = base.RemoveFile(fileId);
30 | if (result)
31 | {
32 | var chat = ClientGuard.CurrentChat;
33 |
34 | // Remove downloading
35 | if (chat.IsFileDownloading(fileId))
36 | chat.RemoveFileDownload(fileId);
37 |
38 | // Notify
39 | var downloadEventArgs = new FileDownloadEventArgs(Name, fileId, 0);
40 | ClientModel.Notifier.PostedFileDeleted(downloadEventArgs);
41 | }
42 | return result;
43 | }
44 | #endregion
45 |
46 | #region dispose
47 | protected override void ReleaseManagedResources()
48 | {
49 | base.ReleaseManagedResources();
50 |
51 | // Remove all posted files.
52 | var chat = ClientGuard.CurrentChat;
53 | foreach (var file in Files)
54 | {
55 | if (file.Id.Owner == chat.User.Id)
56 | chat.RemovePostedFile(Name, file.Id);
57 | }
58 | }
59 | #endregion
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Engine/Model/Client/Entities/ClientUser.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Dto;
2 | using Engine.Model.Common.Entities;
3 | using System;
4 | using System.Drawing;
5 | using System.Security;
6 | using System.Security.Cryptography.X509Certificates;
7 |
8 | namespace Engine.Model.Client.Entities
9 | {
10 | [Serializable]
11 | public class ClientUser : User
12 | {
13 | private int _voiceCounter;
14 | private X509Certificate2 _certificate;
15 |
16 | ///
17 | /// Creates new instance of user.
18 | ///
19 | /// User id.
20 | /// Nick color.
21 | /// User certificate.
22 | [SecuritySafeCritical]
23 | public ClientUser(UserId id, Color color, X509Certificate2 certificate)
24 | : base(id, color)
25 | {
26 | _certificate = certificate;
27 | }
28 |
29 | ///
30 | /// Creates new instance of user.
31 | ///
32 | /// Data transfer object of user.
33 | [SecuritySafeCritical]
34 | public ClientUser(UserDto dto)
35 | : base(dto)
36 | {
37 | _certificate = new X509Certificate2(dto.Certificate);
38 | }
39 |
40 | ///
41 | /// User certificate.
42 | ///
43 | public X509Certificate2 Certificate
44 | {
45 | [SecuritySafeCritical]
46 | get { return _certificate; }
47 | }
48 |
49 | ///
50 | /// Checks is voice active for user.
51 | ///
52 | /// Returns true if voice active, otherwise false.
53 | [SecuritySafeCritical]
54 | public bool IsVoiceActive()
55 | {
56 | return _voiceCounter > 0;
57 | }
58 |
59 | ///
60 | /// Increments voice counter.
61 | /// Counter used to check voice state (enabled/disabled).
62 | ///
63 | [SecuritySafeCritical]
64 | public void IncVoiceCounter()
65 | {
66 | _voiceCounter++;
67 | }
68 |
69 | ///
70 | /// Decrements voice counter.
71 | /// Counter used to check voice state (enabled/disabled).
72 | ///
73 | [SecuritySafeCritical]
74 | public void DecVoiceCounter()
75 | {
76 | if (_voiceCounter == 0)
77 | throw new InvalidOperationException("Can't decrement voice counter.");
78 | _voiceCounter--;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Dto/BinNullable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ThirtyNineEighty.BinarySerializer;
3 |
4 | namespace Engine.Model.Common.Dto
5 | {
6 | ///
7 | /// Represents nullable type for BinarySerializer
8 | ///
9 | [Serializable]
10 | [BinType("BinNullable")]
11 | public sealed class BinNullable
12 | where T: struct
13 | {
14 | [BinField("v")]
15 | public T Value;
16 |
17 | public BinNullable(T value)
18 | {
19 | Value = value;
20 | }
21 |
22 | public static implicit operator T?(BinNullable nullable)
23 | {
24 | return nullable == null ? (T?)null : nullable.Value;
25 | }
26 |
27 | public static implicit operator BinNullable(T value)
28 | {
29 | return new BinNullable(value);
30 | }
31 |
32 | public static implicit operator BinNullable(T? value)
33 | {
34 | if (value == null)
35 | return null;
36 | return new BinNullable(value.Value);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Dto/ColorDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using ThirtyNineEighty.BinarySerializer;
4 |
5 | namespace Engine.Model.Common.Dto
6 | {
7 | [Serializable]
8 | [BinType("ColorDto")]
9 | public class ColorDto
10 | {
11 | [BinField("r")]
12 | public byte Red;
13 |
14 | [BinField("g")]
15 | public byte Green;
16 |
17 | [BinField("b")]
18 | public byte Blue;
19 |
20 | public ColorDto()
21 | {
22 | }
23 |
24 | public ColorDto(Color color)
25 | {
26 | Red = color.R;
27 | Green = color.G;
28 | Blue = color.B;
29 | }
30 |
31 | public Color ToColor()
32 | {
33 | return Color.FromArgb(Red, Green, Blue);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Dto/FileDescriptionDto.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 | using ThirtyNineEighty.BinarySerializer;
4 |
5 | namespace Engine.Model.Common.Dto
6 | {
7 | ///
8 | /// File description data transfer object.
9 | ///
10 | [Serializable]
11 | [BinType("FileDescriptionDto")]
12 | public class FileDescriptionDto
13 | {
14 | [BinField("i")]
15 | public FileId Id;
16 |
17 | [BinField("s")]
18 | public long Size;
19 |
20 | [BinField("n")]
21 | public string Name;
22 |
23 | public FileDescriptionDto(FileDescription file)
24 | : this(file.Id, file.Size, file.Name)
25 | {
26 |
27 | }
28 |
29 | public FileDescriptionDto(FileId id, long size, string name)
30 | {
31 | Id = id;
32 | Size = size;
33 | Name = name;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Dto/MessageDto.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 | using ThirtyNineEighty.BinarySerializer;
4 |
5 | namespace Engine.Model.Common.Dto
6 | {
7 | ///
8 | /// Message data transfer object.
9 | ///
10 | [Serializable]
11 | [BinType("MessageDto")]
12 | public class MessageDto
13 | {
14 | [BinField("i")]
15 | public long Id;
16 |
17 | [BinField("t")]
18 | public DateTime Time;
19 |
20 | [BinField("x")]
21 | public string Text;
22 |
23 | [BinField("o")]
24 | public UserId Owner;
25 |
26 | public MessageDto(Message msg)
27 | {
28 | Id = msg.Id;
29 | Time = msg.Time;
30 | Text = msg.Text;
31 | Owner = msg.Owner;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Dto/RoomDto.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using ThirtyNineEighty.BinarySerializer;
6 |
7 | namespace Engine.Model.Common.Dto
8 | {
9 | ///
10 | /// Room data transfer object.
11 | ///
12 | [Serializable]
13 | [BinType("RoomDto")]
14 | public class RoomDto
15 | {
16 | [BinField("n")]
17 | public string Name;
18 |
19 | [BinField("a")]
20 | public UserId Admin;
21 |
22 | [BinField("u")]
23 | public UserId[] Users;
24 |
25 | [BinField("f")]
26 | public FileDescriptionDto[] Files;
27 |
28 | [BinField("m")]
29 | public MessageDto[] Messages;
30 |
31 | [BinField("t")]
32 | public RoomType Type;
33 |
34 | [BinField("c")]
35 | public UserId[] ConnectTo;
36 |
37 | public RoomDto(
38 | string name
39 | , UserId admin
40 | , IEnumerable users
41 | , IEnumerable files
42 | , IEnumerable messages
43 | , RoomType type
44 | , IEnumerable connectTo)
45 | {
46 | Name = name;
47 | Admin = admin;
48 | Users = users.ToArray();
49 | Files = files.Select(f => f.ToDto()).ToArray();
50 | Messages = messages.Select(m => m.ToDto()).ToArray();
51 |
52 | Type = type;
53 |
54 | if (connectTo != null)
55 | ConnectTo = connectTo.ToArray();
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Dto/UserDto.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Client.Entities;
2 | using Engine.Model.Common.Entities;
3 | using System;
4 | using System.Drawing;
5 | using System.Security.Cryptography.X509Certificates;
6 | using ThirtyNineEighty.BinarySerializer;
7 |
8 | namespace Engine.Model.Common.Dto
9 | {
10 | ///
11 | /// User data transfer object.
12 | ///
13 | [Serializable]
14 | [BinType("UserDto", Version = 2)]
15 | public class UserDto
16 | {
17 | [BinField("n")]
18 | public UserId Id;
19 |
20 | [BinField("c")]
21 | public ColorDto NickColor;
22 |
23 | [BinField("i")]
24 | public byte[] Certificate;
25 |
26 | public UserDto(User user, byte[] certificate)
27 | : this(user.Id, user.NickColor, certificate)
28 | {
29 | }
30 |
31 | public UserDto(ClientUser user)
32 | : this(user, user.Certificate.Export(X509ContentType.Cert))
33 | {
34 |
35 | }
36 |
37 | public UserDto(UserId id, Color color, byte[] certificate)
38 | {
39 | Id = id;
40 | NickColor = new ColorDto(color);
41 | Certificate = certificate;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/AudioQuality.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 |
4 | namespace Engine.Model.Common.Entities
5 | {
6 | [Serializable]
7 | public class AudioQuality : IEquatable
8 | {
9 | public int Channels { get; set; }
10 | public int Bits { get; set; }
11 | public int Frequency { get; set; }
12 |
13 | [SecuritySafeCritical]
14 | public AudioQuality(int channels, int bits, int frequency)
15 | {
16 | if (channels != 2 && channels != 1)
17 | throw new ArgumentException("channels");
18 |
19 | if (bits != 8 && bits != 16)
20 | throw new ArgumentException("bitPerChannel");
21 |
22 | if (frequency <= 0)
23 | throw new ArgumentException("frequency");
24 |
25 | Channels = channels;
26 | Bits = bits;
27 | Frequency = frequency;
28 | }
29 |
30 | [SecuritySafeCritical]
31 | public override string ToString()
32 | {
33 | return string.Format("{0} bits / {1} Hz", Bits, Frequency);
34 | }
35 |
36 | [SecuritySafeCritical]
37 | public override bool Equals(object obj)
38 | {
39 | if (obj is null)
40 | return false;
41 |
42 | if (ReferenceEquals(obj, this))
43 | return true;
44 |
45 | var quality = obj as AudioQuality;
46 | if (quality is null)
47 | return false;
48 |
49 | return Equals(quality);
50 | }
51 |
52 | [SecuritySafeCritical]
53 | public bool Equals(AudioQuality other)
54 | {
55 | if (other is null)
56 | return false;
57 |
58 | if (ReferenceEquals(other, this))
59 | return true;
60 |
61 | return Channels == other.Channels &&
62 | Bits == other.Bits &&
63 | Frequency == other.Frequency;
64 | }
65 |
66 | [SecuritySafeCritical]
67 | public override int GetHashCode()
68 | {
69 | int hashCode = Channels;
70 | hashCode = (hashCode ^ 397) * Bits;
71 | hashCode = (hashCode ^ 397) * Frequency;
72 | return hashCode;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/DownloadingFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Security;
4 |
5 | namespace Engine.Model.Common.Entities
6 | {
7 | public sealed class DownloadingFile :
8 | MarshalByRefObject,
9 | IDisposable
10 | {
11 | private bool _disposed = false;
12 |
13 | ///
14 | /// File Description.
15 | ///
16 | public FileDescription File
17 | {
18 | [SecuritySafeCritical]
19 | get;
20 | [SecurityCritical]
21 | private set;
22 | }
23 |
24 | ///
25 | /// Saving file stream.
26 | ///
27 | public FileStream WriteStream
28 | {
29 | [SecuritySafeCritical]
30 | get;
31 | [SecurityCritical]
32 | private set;
33 | }
34 |
35 | ///
36 | /// Path where file stored.
37 | ///
38 | public string FullName
39 | {
40 | [SecuritySafeCritical]
41 | get;
42 | [SecurityCritical]
43 | private set;
44 | }
45 |
46 | ///
47 | /// Create the instance of DownloadingFile.
48 | ///
49 | /// File description.
50 | /// Path where the file will be stored on disc.
51 | [SecuritySafeCritical]
52 | public DownloadingFile(FileDescription file, string fullName)
53 | {
54 | File = file;
55 | FullName = fullName;
56 | WriteStream = new FileStream(fullName, FileMode.Create, FileAccess.Write);
57 | }
58 |
59 | ///
60 | /// Dispose the resources of DownloadingFile.
61 | ///
62 | [SecuritySafeCritical]
63 | public void Dispose()
64 | {
65 | if (_disposed)
66 | return;
67 |
68 | _disposed = true;
69 |
70 | if (WriteStream != null)
71 | {
72 | WriteStream.Dispose();
73 | WriteStream = null;
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/FileId.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using ThirtyNineEighty.BinarySerializer;
4 |
5 | namespace Engine.Model.Common.Entities
6 | {
7 | [Serializable]
8 | [BinType("FieldIdDto")]
9 | public struct FileId : IEquatable
10 | {
11 | [BinField("i")]
12 | private int _id;
13 |
14 | [BinField("o")]
15 | private UserId _owner;
16 |
17 | ///
18 | /// Create file identification.
19 | ///
20 | /// File identificator.
21 | /// File owner user id.
22 | [SecuritySafeCritical]
23 | public FileId(int id, UserId owner)
24 | {
25 | _id = id;
26 | _owner = owner;
27 | }
28 |
29 | ///
30 | /// File identificator.
31 | ///
32 | public int Id { get { return _id; } }
33 |
34 | ///
35 | /// File owner user id.
36 | ///
37 | public UserId Owner { get { return _owner; } }
38 |
39 | [SecuritySafeCritical]
40 | public static bool operator == (FileId first, FileId second)
41 | {
42 | return first.Equals(second);
43 | }
44 |
45 | [SecuritySafeCritical]
46 | public static bool operator != (FileId first, FileId second)
47 | {
48 | return !first.Equals(second);
49 | }
50 |
51 | [SecuritySafeCritical]
52 | public override bool Equals(object obj)
53 | {
54 | if (obj == null)
55 | return false;
56 | if (!(obj is FileId))
57 | return false;
58 | return Equals((FileId)obj);
59 | }
60 |
61 | [SecuritySafeCritical]
62 | public bool Equals(FileId other)
63 | {
64 | return Id == other.Id && Owner == other.Owner;
65 | }
66 |
67 | [SecuritySafeCritical]
68 | public override int GetHashCode()
69 | {
70 | return (Id * 397) ^ Owner.GetHashCode();
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/Message.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Dto;
2 | using System;
3 | using System.Security;
4 |
5 | namespace Engine.Model.Common.Entities
6 | {
7 | ///
8 | /// User message.
9 | ///
10 | [Serializable]
11 | public class Message
12 | {
13 | ///
14 | /// Message id.
15 | ///
16 | public readonly long Id;
17 |
18 | ///
19 | /// Message sender.
20 | ///
21 | public readonly UserId Owner;
22 |
23 | ///
24 | /// Time when message was sent.
25 | ///
26 | public readonly DateTime Time;
27 |
28 | ///
29 | /// Message text.
30 | ///
31 | public string Text;
32 |
33 | [SecuritySafeCritical]
34 | public Message(MessageDto dto)
35 | : this(dto.Id, dto.Owner, dto.Text, dto.Time)
36 | {
37 |
38 | }
39 |
40 | [SecuritySafeCritical]
41 | public Message(long id, UserId owner, string text)
42 | : this(id, owner, text, DateTime.UtcNow)
43 | {
44 | }
45 |
46 | [SecuritySafeCritical]
47 | public Message(long id, UserId owner, string text, DateTime time)
48 | {
49 | Owner = owner;
50 | Id = id;
51 | Text = text;
52 | Time = time;
53 | }
54 |
55 | ///
56 | /// Trying to concat other message with this.
57 | ///
58 | /// Other message which trying to contact with this.
59 | /// If result is true then message was concated, otherwise - false.
60 | [SecuritySafeCritical]
61 | public bool TryConcat(Message other)
62 | {
63 | if (Owner != other.Owner)
64 | return false;
65 |
66 | const double ConcatMinutes = 1;
67 | if ((other.Time - Time).TotalMinutes > ConcatMinutes)
68 | return false;
69 |
70 | Text += string.Format("{0}{1}", Environment.NewLine, other.Text);
71 | return true;
72 | }
73 |
74 | [SecuritySafeCritical]
75 | public MessageDto ToDto()
76 | {
77 | return new MessageDto(this);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/RoomType.cs:
--------------------------------------------------------------------------------
1 | namespace Engine.Model.Common.Entities
2 | {
3 | public enum RoomType
4 | {
5 | Unknown = -1,
6 | Chat = 1,
7 | Voice = 2,
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/SoundPack.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ThirtyNineEighty.BinarySerializer;
3 |
4 | namespace Engine.Model.Common.Entities
5 | {
6 | ///
7 | /// Recorderd voice data.
8 | ///
9 | [Serializable]
10 | [BinType("SoundPackDto")]
11 | public class SoundPack
12 | {
13 | ///
14 | /// Recorded data.
15 | ///
16 | [BinField("d")]
17 | public byte[] Data;
18 |
19 | ///
20 | /// Channels count.
21 | ///
22 | [BinField("c")]
23 | public int Channels;
24 |
25 | ///
26 | /// Pits per channel count.
27 | ///
28 | [BinField("b")]
29 | public int BitPerChannel;
30 |
31 | ///
32 | /// Frequency.
33 | ///
34 | [BinField("f")]
35 | public int Frequency;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/SystemMessageId.cs:
--------------------------------------------------------------------------------
1 | namespace Engine.Model.Common.Entities
2 | {
3 | // TODO: rus
4 | public enum SystemMessageId
5 | {
6 | None = 0,
7 |
8 | ApiNotSupported = 1, // Api not supperted by server.
9 | ConnectionRetryAttempt = 2, // Connection retry attempt...
10 |
11 | NotRegisteredBadName = 10, // Connection cant be registered with this nick. Invalid characters.
12 | NotRegisteredNameAlreadyExist = 11, // Connection cant be registered with this nick. Nick already exist.
13 | NotRegisteredBadThumbprint = 12, // Connection cant be registered. User id thumbprint does not match certificate.
14 |
15 | RoomAdminChanged = 20, // Вы назначены администратором комнаты. {0} - название команаты.
16 | RoomAccessDenied = 21, // Вы не входите в состав этой комнаты.
17 | RoomAlreadyExist = 22, // Комната с таким именем уже создана, выберите другое имя.
18 | RoomCantLeaveMainRoom = 23, // Невозможно выйти из основной комнаты.
19 | RoomItsMainRoom = 24, // Невозможно произвести это действие с основной комнатой.
20 | RoomNotExist = 25, // Команата с таким именем не существует.
21 | RoomUserNotExist = 26, // Такого пользователя нет в комнате.
22 |
23 | FileRemoveAccessDenied = 30, // Вы не можете удалить данный файл. Не хватает прав.
24 | FileRemoved = 31, // Файл удален {0} - имя файла.
25 |
26 | MessageEditAccessDenied = 40, // Вы не можете редактировать это сообщение.
27 |
28 | P2PUserNotExist = 50, // Данного пользователя не существует.
29 |
30 | InvalidPassword = 60, // Invalid password.
31 | TextCommandNotFound = 61, // Text command not found.
32 | TextCommandsList = 62, // Text commands list.
33 | TextCommandInvalidParams = 63, // Text command params are invalid
34 | TextCommandMessageId = 64, // Result of showMessageId command
35 | TextCommandUsersList = 65 // Result with user ids
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/User.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Dto;
2 | using System;
3 | using System.Drawing;
4 | using System.Security;
5 |
6 | namespace Engine.Model.Common.Entities
7 | {
8 | // TODO: add dispose
9 | [Serializable]
10 | public class User :
11 | IEquatable
12 | {
13 | private readonly UserId _id;
14 | private readonly Color _nickColor;
15 |
16 | ///
17 | /// Creates new instance of user.
18 | ///
19 | /// User id.
20 | /// Nick color.
21 | [SecuritySafeCritical]
22 | public User(UserId id, Color nickColor)
23 | {
24 | _id = id;
25 | _nickColor = nickColor;
26 | }
27 |
28 | ///
29 | /// Creates new instance of user.
30 | ///
31 | /// Data transfer object of user.
32 | [SecuritySafeCritical]
33 | public User(UserDto dto)
34 | {
35 | _id = dto.Id;
36 | _nickColor = dto.NickColor.ToColor();
37 | }
38 |
39 | ///
40 | /// User id.
41 | ///
42 | public UserId Id
43 | {
44 | [SecuritySafeCritical]
45 | get { return _id; }
46 | }
47 |
48 | ///
49 | /// Nick color.
50 | ///
51 | public Color NickColor
52 | {
53 | [SecuritySafeCritical]
54 | get { return _nickColor; }
55 | }
56 |
57 | [SecuritySafeCritical]
58 | public override bool Equals(object obj)
59 | {
60 | if (obj is null)
61 | return false;
62 |
63 | if (ReferenceEquals(obj, this))
64 | return true;
65 |
66 | var user = obj as User;
67 | if (user is null)
68 | return false;
69 |
70 | return Equals(user);
71 | }
72 |
73 | [SecuritySafeCritical]
74 | public override int GetHashCode()
75 | {
76 | return _id.GetHashCode();
77 | }
78 |
79 | [SecuritySafeCritical]
80 | public bool Equals(User user)
81 | {
82 | if (user is null)
83 | return false;
84 |
85 | if (ReferenceEquals(user, this))
86 | return true;
87 |
88 | return Equals(_id, user.Id);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Entities/VoiceRoom.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Security;
4 |
5 | namespace Engine.Model.Common.Entities
6 | {
7 | [Serializable]
8 | public class VoiceRoom : Room
9 | {
10 | ///
11 | /// Create new voice room instance.
12 | ///
13 | /// Admin nick.
14 | /// Room name.
15 | [SecuritySafeCritical]
16 | public VoiceRoom(UserId admin, string name)
17 | : base(admin, name)
18 | {
19 |
20 | }
21 |
22 | ///
23 | /// Create new voice room instance.
24 | ///
25 | /// Admin nick.
26 | /// Room name.
27 | /// Initial room users list.
28 | [SecuritySafeCritical]
29 | public VoiceRoom(UserId admin, string name, IEnumerable initialUsers)
30 | : base(admin, name, initialUsers)
31 | {
32 |
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Engine/Model/Common/Guard.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using System.Threading;
4 |
5 | namespace Engine.Model
6 | {
7 | public abstract class Guard : MarshalByRefObject, IDisposable
8 | where T : class
9 | {
10 | #if DEBUG
11 | private const int TimeOut = -1;
12 | #else
13 | private const int TimeOut = 10000;
14 | #endif
15 |
16 | [ThreadStatic] protected static Guard _current;
17 | protected T _obj;
18 |
19 | [SecurityCritical]
20 | protected Guard(T obj)
21 | {
22 | if (!Monitor.TryEnter(obj, TimeOut))
23 | throw new InvalidOperationException("model lock timeout");
24 |
25 | _obj = obj;
26 |
27 | if (_current == null)
28 | _current = this;
29 | }
30 |
31 | [SecuritySafeCritical]
32 | public void Dispose()
33 | {
34 | if (_current == this)
35 | _current = null;
36 |
37 | var obj = _obj;
38 | _obj = default;
39 |
40 | Monitor.Exit(obj);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Engine/Model/Server/Entities/ServerChat.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Dto;
2 | using Engine.Model.Common.Entities;
3 | using System;
4 | using System.Linq;
5 | using System.Security;
6 |
7 | namespace Engine.Model.Server.Entities
8 | {
9 | [Serializable]
10 | public class ServerChat : Chat
11 | {
12 | [SecurityCritical]
13 | public ServerChat()
14 | {
15 | AddRoom(new ServerRoom(UserId.Empty, MainRoomName));
16 | }
17 |
18 | #region users
19 | ///
20 | /// Returns all users from room as dtos.
21 | ///
22 | /// Room name.
23 | [SecuritySafeCritical]
24 | public UserDto[] GetRoomUserDtos(string roomName)
25 | {
26 | var room = GetRoom(roomName);
27 | return room.Users
28 | .Select(CreateDto)
29 | .ToArray();
30 | }
31 |
32 | [SecuritySafeCritical]
33 | private UserDto CreateDto(UserId userId)
34 | {
35 | var user = GetUser(userId);
36 | var certificate = ServerModel.Server.GetCertificate(userId);
37 | return new UserDto(user, certificate.RawData);
38 | }
39 | #endregion
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Engine/Model/Server/Entities/ServerRoom.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common.Entities;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Security;
6 |
7 | namespace Engine.Model.Server.Entities
8 | {
9 | [Serializable]
10 | public class ServerRoom : Room
11 | {
12 | ///
13 | /// Create the room.
14 | ///
15 | /// User id which be administrator of the room.
16 | /// Room name.
17 | [SecuritySafeCritical]
18 | public ServerRoom(UserId admin, string name)
19 | : base(admin, name)
20 | {
21 |
22 | }
23 |
24 | ///
25 | /// Create the room.
26 | ///
27 | /// User id which be administrator of the room.
28 | /// Room name.
29 | /// Initial room users list.
30 | [SecuritySafeCritical]
31 | public ServerRoom(UserId admin, string name, IEnumerable initialUsers)
32 | : base(admin, name, initialUsers)
33 | {
34 |
35 | }
36 |
37 | #region users
38 | [SecuritySafeCritical]
39 | public IEnumerable GetUsers()
40 | {
41 | return _users.Select(n => ServerGuard.Current.GetUser(n));
42 | }
43 | #endregion
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Engine/Model/Server/ServerGuard.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Server.Entities;
2 | using System.Security;
3 |
4 | namespace Engine.Model.Server
5 | {
6 | public class ServerGuard : Guard
7 | {
8 | [SecurityCritical]
9 | public ServerGuard(ServerChat chat)
10 | : base(chat)
11 | {
12 |
13 | }
14 |
15 | public ServerChat Chat
16 | {
17 | [SecuritySafeCritical]
18 | get { return _obj; }
19 | }
20 |
21 | public static ServerChat Current
22 | {
23 | [SecuritySafeCritical]
24 | get { return ((ServerGuard)_current).Chat; }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Engine/Model/Server/ServerInitializer.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography.X509Certificates;
2 |
3 | namespace Engine.Model.Server
4 | {
5 | public class ServerInitializer
6 | {
7 | public string AdminPassword { get; set; }
8 | public string PluginsPath { get; set; }
9 | public string[] ExcludedPlugins { get; set; }
10 | public X509Certificate2 Certificate { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Engine/Model/Server/ServerNotifier.cs:
--------------------------------------------------------------------------------
1 | using Engine.Model.Common;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Security;
6 |
7 | namespace Engine.Model.Server
8 | {
9 | [SecuritySafeCritical]
10 | public class ServerNotifier : Notifier
11 | {
12 | [SecuritySafeCritical]
13 | public override IEnumerable