2017-01-08 10:17:07 -05:00
/ *
* MIT License
*
* Copyright ( c ) 2017 Michael VanOverbeek and ShiftOS devs
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
* /
using System ;
2017-01-08 09:57:10 -05:00
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
using ShiftOS.Objects ;
using NetSockets ;
using System.Windows.Forms ;
using System.Threading ;
using ShiftOS ;
using static ShiftOS . Engine . SaveSystem ;
using Newtonsoft.Json ;
2017-04-14 13:06:13 -04:00
using System.Net.Sockets ;
2017-05-05 11:34:17 -04:00
using System.Diagnostics ;
2017-01-08 09:57:10 -05:00
namespace ShiftOS.Engine
{
public static class ServerManager
{
public static void PrintDiagnostics ( )
{
Console . WriteLine ( $ @ "{{CLIENT_DIAGNOSTICS}}
{ { GUID } } : { thisGuid }
{ { CLIENT_DATA } } :
{ JsonConvert . SerializeObject ( client , Formatting . Indented ) } ");
}
2017-01-21 16:23:10 -05:00
public static Guid thisGuid { get ; private set ; }
2017-01-08 09:57:10 -05:00
private static NetObjectClient client { get ; set ; }
2017-04-02 18:29:42 -04:00
private static bool UserDisconnect = false ;
2017-01-08 09:57:10 -05:00
2017-05-06 09:44:47 -04:00
public static long DigitalSocietyPing
2017-05-05 11:34:17 -04:00
{
get ;
private set ;
}
2017-01-08 09:57:10 -05:00
public static void Disconnect ( )
{
2017-04-02 18:29:42 -04:00
UserDisconnect = true ;
2017-01-08 09:57:10 -05:00
if ( client ! = null )
{
client . Disconnect ( ) ;
}
Disconnected ? . Invoke ( ) ;
}
public static event EmptyEventHandler Disconnected ;
public static void InitiateMUDHack ( )
{
MessageReceived + = ServerManager_MessageReceived ;
SendMessage ( "mudhack_init" , "" ) ;
}
public static event Action < string > ServerPasswordGenerated ;
public static event EmptyEventHandler ServerAccessGranted ;
public static event EmptyEventHandler ServerAccessDenied ;
public static event Action < string > GUIDReceived ;
public static event Action < List < OnlineUser > > UsersReceived ;
private static void ServerManager_MessageReceived ( ServerMessage msg )
{
switch ( msg . Name )
{
case "mudhack_users" :
UsersReceived ? . Invoke ( JsonConvert . DeserializeObject < List < OnlineUser > > ( msg . Contents ) ) ;
break ;
case "mudhack_init" :
ServerPasswordGenerated ? . Invoke ( msg . Contents ) ;
break ;
case "mudhack_denied" :
ServerAccessDenied ? . Invoke ( ) ;
break ;
case "mudhack_granted" :
ServerAccessGranted ? . Invoke ( ) ;
break ;
case "getguid_fromserver" :
if ( SaveSystem . CurrentSave . Username = = msg . Contents )
{
client . Send ( new NetObject ( "yes_i_am" , new ServerMessage
{
Name = "getguid_reply" ,
GUID = msg . GUID ,
Contents = thisGuid . ToString ( ) ,
} ) ) ;
}
break ;
case "getguid_reply" :
GUIDReceived ? . Invoke ( msg . Contents ) ;
break ;
}
}
public static void Detach_ServerManager_MessageReceived ( )
{
MessageReceived - = new ServerMessageReceived ( ServerManager_MessageReceived ) ;
}
public static void Initiate ( string mud_address , int port )
{
client = new NetObjectClient ( ) ;
2017-04-02 18:29:42 -04:00
client . OnDisconnected + = ( o , a ) = >
{
if ( ! UserDisconnect )
{
2017-05-13 15:51:19 -04:00
Desktop . PushNotification ( "digital_society_connection" , "Disconnected from Digital Society." , "The ShiftOS kernel has been disconnected from the Digital Society. We are attempting to re-connect you." ) ;
2017-04-02 18:29:42 -04:00
TerminalBackend . PrefixEnabled = true ;
ConsoleEx . ForegroundColor = ConsoleColor . Red ;
ConsoleEx . Bold = true ;
Console . Write ( $@"Disconnected from MUD: " ) ;
ConsoleEx . Bold = false ;
ConsoleEx . Italic = true ;
ConsoleEx . ForegroundColor = ConsoleColor . DarkYellow ;
Console . WriteLine ( "You have been disconnected from the multi-user domain for an unknown reason. Your save data is preserved within the kernel and you will be reconnected shortly." ) ;
TerminalBackend . PrefixEnabled = true ;
TerminalBackend . PrintPrompt ( ) ;
Initiate ( mud_address , port ) ;
}
} ;
2017-01-08 09:57:10 -05:00
client . OnReceived + = ( o , a ) = >
{
2017-05-05 11:34:17 -04:00
if ( PingTimer . IsRunning )
{
2017-05-06 09:44:47 -04:00
DigitalSocietyPing = PingTimer . ElapsedMilliseconds ;
2017-05-05 11:34:17 -04:00
PingTimer . Reset ( ) ;
}
2017-01-08 09:57:10 -05:00
var msg = a . Data . Object as ServerMessage ;
if ( msg . Name = = "Welcome" )
{
thisGuid = new Guid ( msg . Contents ) ;
GUIDReceived ? . Invoke ( msg . Contents ) ;
2017-03-11 10:28:16 -05:00
TerminalBackend . PrefixEnabled = true ;
TerminalBackend . PrintPrompt ( ) ;
2017-01-08 09:57:10 -05:00
}
2017-03-07 14:56:48 -05:00
else if ( msg . Name = = "allusers" )
{
foreach ( var acc in JsonConvert . DeserializeObject < string [ ] > ( msg . Contents ) )
{
Console . WriteLine ( acc ) ;
}
2017-03-09 16:46:34 -05:00
TerminalBackend . PrintPrompt ( ) ;
2017-03-07 14:56:48 -05:00
}
2017-01-14 10:28:57 -05:00
else if ( msg . Name = = "update_your_cp" )
{
var args = JsonConvert . DeserializeObject < Dictionary < string , object > > ( msg . Contents ) ;
if ( args [ "username" ] as string = = SaveSystem . CurrentSave . Username )
{
2017-02-18 11:19:54 -05:00
SaveSystem . CurrentSave . Codepoints + = ( long ) args [ "amount" ] ;
2017-02-18 11:22:19 -05:00
Desktop . InvokeOnWorkerThread ( new Action ( ( ) = >
{
Infobox . Show ( $"MUD Control Centre" , $"Someone bought an item in your shop, and they have paid {args[" amount "]}, and as such, you have been granted these Codepoints." ) ;
} ) ) ;
2017-01-14 10:28:57 -05:00
SaveSystem . SaveGame ( ) ;
}
}
2017-01-08 09:57:10 -05:00
else if ( msg . Name = = "broadcast" )
{
Console . WriteLine ( msg . Contents ) ;
}
2017-05-03 11:51:56 -04:00
else if ( msg . Name = = "forward" )
{
MessageReceived ? . Invoke ( JsonConvert . DeserializeObject < ServerMessage > ( msg . Contents ) ) ;
}
2017-01-08 09:57:10 -05:00
else if ( msg . Name = = "Error" )
{
var ex = JsonConvert . DeserializeObject < Exception > ( msg . Contents ) ;
TerminalBackend . PrefixEnabled = true ;
2017-03-09 16:46:34 -05:00
ConsoleEx . ForegroundColor = ConsoleColor . Red ;
ConsoleEx . Bold = true ;
Console . Write ( $@"{{MUD_ERROR}}: " ) ;
ConsoleEx . Bold = false ;
ConsoleEx . Italic = true ;
2017-03-09 16:14:35 -05:00
ConsoleEx . ForegroundColor = ConsoleColor . DarkYellow ;
2017-03-09 16:46:34 -05:00
Console . WriteLine ( ex . Message ) ;
2017-01-08 09:57:10 -05:00
TerminalBackend . PrefixEnabled = true ;
2017-03-09 16:46:34 -05:00
TerminalBackend . PrintPrompt ( ) ;
2017-01-08 09:57:10 -05:00
}
else
{
MessageReceived ? . Invoke ( msg ) ;
}
} ;
2017-04-14 13:06:13 -04:00
try
{
client . Connect ( mud_address , port ) ;
}
catch ( SocketException ex )
{
System . Diagnostics . Debug . Print ( ex . ToString ( ) ) ;
Initiate ( mud_address , port ) ;
}
2017-01-08 09:57:10 -05:00
}
2017-05-05 11:34:17 -04:00
private static Stopwatch PingTimer = new Stopwatch ( ) ;
2017-01-08 09:57:10 -05:00
public static void SendMessage ( string name , string contents )
{
var sMsg = new ServerMessage
{
Name = name ,
Contents = contents ,
GUID = thisGuid . ToString ( ) ,
} ;
2017-05-05 11:34:17 -04:00
PingTimer . Start ( ) ;
2017-01-08 09:57:10 -05:00
client . Send ( new NetObject ( "msg" , sMsg ) ) ;
}
private static bool singleplayer = false ;
public static bool IsSingleplayer { get { return singleplayer ; } }
public static void StartLANServer ( )
{
singleplayer = true ;
ShiftOS . Server . Program . ServerStarted + = ( address ) = >
{
Console . WriteLine ( $"Connecting to {address}..." ) ;
Initiate ( address , 13370 ) ;
} ;
Disconnected + = ( ) = >
{
ShiftOS . Server . Program . Stop ( ) ;
} ;
ShiftOS . Server . Program . Main ( new [ ] { "" } ) ;
}
public static event ServerMessageReceived MessageReceived ;
2017-05-03 11:51:56 -04:00
public static void Forward ( string targetGUID , string v , string message )
{
var smsg = new ServerMessage
{
GUID = targetGUID ,
Name = v ,
Contents = message
} ;
ServerManager . SendMessage ( "mud_forward" , JsonConvert . SerializeObject ( smsg ) ) ;
}
2017-01-08 09:57:10 -05:00
}
public delegate void ServerMessageReceived ( ServerMessage msg ) ;
public class MultiplayerOnlyAttribute : Attribute
{
/// <summary>
/// Marks this application as a multiplayer-only application.
/// </summary>
public MultiplayerOnlyAttribute ( )
{
}
}
}