MudEngine:

- Login command now automatically disconnects a user if they are currently logged into the server when another user attempts to login with the same credentials.
 - Login command now loads saved players when a character name is entered that has previously been saved.
 - FileManager.GetData() now supports ignoring simi-colons in data files. These can be used as comments if needed.
 - MudEngine.GameManagement.Game.TimeOfDayOptions has been removed from the Game Type. It is now just MudEngine.GameManagement.TimeOfDayOptions.
 - BaseCharacter will no longer try to save the character if the supplied filename is blank
 - BaseCharacter will now send a disconnect message of 'Goodbye!' upon the player being disconnected from the server.
 - ScriptEngine.ScriptPath now returns a absolute path.
 - Script File compilation within ScriptEngine.Initialization is now supported. This allows developers to write their MUD's using Scripts and letting the server compile them during server startup rather than use the ScriptCompiler.exe to pre-compile scripts now.
 - Custom Game Types are now supported. Only 1 Type may inherit from MudEngine.GameManagement.Game at a time. To use, create a file, write a script that inherits from Game and run the server.
 - ScriptEngine.GetObjectOf(string) method adding. Returns a object that inherits from the Type supplied in the parameter.
 - Deleted StartupObject.cs
 - Deleted Startup.dat 

MudOfflineExample:
 - Updated to reflect the TimeOfDayOptions change in MudEngine.csproj

MudServer:
 - Added MyGame.cs inside Debug/bin/scripts. This is a example script showing how to inherit from Game and write a custom Game Type. This Type is used when the Server runs rather than the Engine Game Type.
 - Server startup re-wrote to compile scripts during startup, scan them via the script engine for any custom Types that inherit from Game, and use the if needed instead of the default Engine Type.
 - Server now uses a Settings.ini file to allow configuration of the Script Engine by users. Provides them the ability to now customize where scripts are stored and their file extension.
 - Deleted Scripts.dll, as the Server now generates one at runtime each time it is ran.

As of this commit, users will not need to use C# to compile their MUD's any longer. Compile the Server and run it. Scripts are now fully implemented (however not fully tested).
This commit is contained in:
Scionwest_cp 2010-08-05 17:46:30 -07:00
parent 0f45ecec53
commit c3c2d22ec7
17 changed files with 181 additions and 74 deletions

View file

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using MudEngine.FileSystem;
using MudEngine.GameObjects.Characters;
using MudEngine.GameManagement;
using MudEngine.Commands;
@ -20,8 +22,12 @@ namespace MudEngine.Commands
if (player.ActiveGame.IsMultiplayer)
player.Disconnect();
else
{
//Save the player prior to attempting to shutdown.
//Player saving is handled in the server disconnect code but not in game shutdown.
player.Save(Path.Combine(player.ActiveGame.DataPaths.Players, player.Filename));
player.ActiveGame.Shutdown();
}
return new CommandResults();
}
}

View file

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using MudEngine.FileSystem;
using MudEngine.GameObjects.Characters;
using MudEngine.GameManagement;
using MudEngine.Commands;
@ -22,37 +24,44 @@ namespace MudEngine.Commands
player.Send(player.ActiveGame.Story);
player.Send("");
bool isLegal = false;
while (!isLegal)
{
player.Send("Enter Character Name: ", false);
string input = player.ReadInput();
bool foundName = false;
foreach (BaseCharacter bc in player.ActiveGame.PlayerCollection)
string input = player.ReadInput();
Boolean playerFound = false;
string savedFile = "";
//See if this character already exists.
foreach (string filename in Directory.GetFiles(player.ActiveGame.DataPaths.Players))
{
if (bc.Name == input)
if (Path.GetFileNameWithoutExtension(filename).ToLower() == input.ToLower())
{
player.Send("Character name already taken.");
foundName = true;
//TODO: Ask for password.
savedFile = filename;
playerFound = true;
break;
}
}
if (!foundName)
//Next search if there is an existing player already logged in with this name, if so disconnect them.
foreach (BaseCharacter character in player.ActiveGame.PlayerCollection)
{
if (input == "")
continue;
else
if (character.Name.ToLower() == input.ToLower())
{
isLegal = true;
player.Name = input;
}
character.Disconnect();
}
}
//Now assign this name to this player if this is a new toon or load the player if the file exists.
if (!playerFound)
{
player.Name = input;
player.Send("Welcome " + player.Name + "!");
}
else
{
player.Load(savedFile);
player.Send("Welcome back " + player.Name + "!");
}
player.CommandSystem.ExecuteCommand("Look", player);
return new CommandResults();
}

View file

@ -56,6 +56,10 @@ namespace MudEngine.FileSystem
{
foreach (string line in File.ReadAllLines(filename))
{
//Ignore comments
if (line.StartsWith(";"))
continue;
if (line.StartsWith(name))
return line.Substring(name.Length + 1); //Accounts for name=value;
}

View file

@ -20,6 +20,16 @@ using MudEngine.Scripting;
namespace MudEngine.GameManagement
{
#region Custom Types
public enum TimeOfDayOptions
{
AlwaysDay,
AlwaysNight,
Transition,
}
#endregion
/// <summary>
/// Manages all of the projects settings.
/// </summary>
@ -28,25 +38,6 @@ namespace MudEngine.GameManagement
public class Game
{
#region ==== Properties & Types ====
#region Custom Types
public enum TimeOfDayOptions
{
AlwaysDay,
AlwaysNight,
Transition,
}
/// <summary>
/// Gets or Sets what time of day the world is currently in.
/// </summary>
[Category("Day Management")]
[Description("Set what time of day the world will take place in.")]
public TimeOfDayOptions TimeOfDay
{
get;
set;
}
#endregion
#region Game Object Setup
/// <summary>
@ -129,6 +120,13 @@ namespace MudEngine.GameManagement
/// </summary>
public bool HideRoomNames { get; set; }
/// <summary>
/// Gets or Sets what time of day the world is currently in.
/// </summary>
[Category("Day Management")]
[Description("Set what time of day the world will take place in.")]
public TimeOfDayOptions TimeOfDay { get; set; }
/// <summary>
/// Gets or Sets how long in minutes it takes to transition from day to night.
/// </summary>

View file

@ -89,6 +89,10 @@ namespace MudEngine.GameObjects.Characters
public override void Save(string filename)
{
//Don't attempt to save a blank filename.
if (String.IsNullOrEmpty(filename))
return;
base.Save(filename);
FileManager.WriteLine(filename, this.IsControlled.ToString(), "IsControlled");
@ -224,6 +228,7 @@ namespace MudEngine.GameObjects.Characters
string filePath = Path.Combine(ActiveGame.DataPaths.Players, Filename);
this.Save(filePath);
Send("Goodbye!");
IsActive = false;
client.Close();

View file

@ -83,14 +83,8 @@
<Compile Include="Scripting\GameObject.cs" />
<Compile Include="Scripting\GameObjectCollection.cs" />
<Compile Include="Scripting\ScriptEngine.cs" />
<Compile Include="Scripting\StartupObject.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<None Include="startup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -11,6 +11,7 @@ using System.IO;
using System.Text;
using System.Reflection;
using MudEngine.FileSystem;
using MudEngine.GameObjects;
using MudEngine.GameObjects.Characters;
using MudEngine.GameManagement;
@ -28,7 +29,19 @@ namespace MudEngine.Scripting
/// <summary>
/// Path to the the script files directory
/// </summary>
public string ScriptPath { get; set; }
public string ScriptPath
{
get
{
return _ScriptPath;
}
set
{
_ScriptPath = Path.Combine(FileManager.GetDataPath(SaveDataTypes.Root), value);
}
}
string _ScriptPath;
public string InstallPath { get; private set; }
public GameObjectCollection ObjectCollection { get; private set; }
@ -89,7 +102,7 @@ namespace MudEngine.Scripting
ScriptExtension = ".cs";
//Get our current install path
ScriptPath = Path.Combine(Environment.CurrentDirectory, "Scripts");
ScriptPath = "Scripts";
InstallPath = Environment.CurrentDirectory;
GameObjects = new List<GameObject>();
_AssemblyCollection = new List<Assembly>();
@ -159,12 +172,13 @@ namespace MudEngine.Scripting
//Compile the scripts with the C# CodeProvider
CSharpCodeProvider codeProvider = new CSharpCodeProvider(providerOptions);
CompilerResults results = new CompilerResults(new TempFileCollection());
scripts = Directory.GetFiles(ScriptPath, "*.Mud", SearchOption.AllDirectories);
scripts = Directory.GetFiles(ScriptPath, "*" + ScriptExtension, SearchOption.AllDirectories);
results = codeProvider.CompileAssemblyFromFile(param, scripts);
//Delete the temp folder
//Directory.Delete("temp", true);
ScriptPath = oldPath;
_ScriptAssembly = results.CompiledAssembly;
//if we encountered errors we need to log them to our ErrorMessages property
if (results.Errors.Count >= 1)
@ -224,6 +238,11 @@ namespace MudEngine.Scripting
Log.Write(t.Name + " script loaded.");
continue;
}
else if (t.BaseType.Name == "Game")
{
GameObject obj = new GameObject(Activator.CreateInstance(t, null), t.Name);
GameObjects.Add(obj);
}
}
}
}
@ -253,7 +272,16 @@ namespace MudEngine.Scripting
private void InitializeSourceFiles()
{
Log.Write("Source file scripts is not supported! Please change the script engine settings to load pre-compiled Assemblies!");
string[] scripts = Directory.GetFiles(ScriptPath, "*.cs", SearchOption.AllDirectories);
if (scripts.Length == 0)
{
Log.Write("No un-compiled scripts located!");
return;
}
CompileScripts();
_AssemblyCollection.Add(_ScriptAssembly);
}
public GameObject GetObject(string objectName)
@ -271,5 +299,16 @@ namespace MudEngine.Scripting
return null;
}
public GameObject GetObjectOf(string baseTypeName)
{
foreach (GameObject obj in GameObjects)
{
if (obj.Instance.GetType().BaseType.Name == baseTypeName)
return obj;
}
return null;
}
}
}

View file

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MudEngine.Scripting
{
public class StartupObject
{
public StartupObject()
{
}
}
}

View file

@ -1 +0,0 @@
PlayerClass=P

View file

@ -27,7 +27,7 @@ namespace MUDGame
game.HideRoomNames = false;
game.PreCacheObjects = true;
game.ProjectPath = FileManager.GetDataPath(SaveDataTypes.Root);
game.TimeOfDay = Game.TimeOfDayOptions.Transition;
game.TimeOfDay = TimeOfDayOptions.Transition;
game.TimeOfDayTransition = 30;
game.Version = "0.1";
game.Website = "http://MudDesigner.Codeplex.com";

View file

@ -1,2 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:ignore</Name><Value>obj
</Value></Property><Property><Name>svn:ignore</Name><Value>obj
Settings.ini
</Value></Property></Properties></ItemProperties>

View file

@ -55,6 +55,11 @@
<Name>MudEngine</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Settings.ini">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net.Sockets;
using System.Text;
using MudEngine.FileSystem;
using MudEngine.GameManagement;
using MudEngine.GameObjects.Characters;
using MudEngine.Scripting;
using MUDGame; //Pulling this from the example game, no sense re-writing what already exists.
namespace MudServer
@ -15,6 +17,46 @@ namespace MudServer
{
static void Main(string[] args)
{
ScriptEngine scriptEngine;
Game game;
//Re-create the settings file if it is missing
if (!File.Exists("Settings.ini"))
{
Log.Write("Settings.ini missing!");
FileManager.WriteLine("Settings.ini", "Scripts", "ScriptPath");
FileManager.WriteLine("Settings.ini", ".cs", "ScriptExtension");
}
scriptEngine = new ScriptEngine(new Game(), ScriptEngine.ScriptTypes.SourceFiles);
scriptEngine.ScriptPath = FileManager.GetData("Settings.ini", "ScriptPath");
scriptEngine.ScriptExtension = FileManager.GetData("Settings.ini", "ScriptExtension");
//scriptEngine.CompileScripts();
scriptEngine.Initialize();
GameObject obj = scriptEngine.GetObjectOf("Game");
if (obj == null)
{
game = new Game();
obj = new GameObject(game, "Game");
scriptEngine = new ScriptEngine((Game)obj.Instance, ScriptEngine.ScriptTypes.Assembly);
}
else
{
game = (Game)obj.Instance;
scriptEngine = new ScriptEngine(game, ScriptEngine.ScriptTypes.Assembly);
}
scriptEngine.Initialize();
Console.WriteLine(game.GameTitle);
Console.ReadKey();
/*
Game game = new Game();
Zeroth realm = new Zeroth(game);
@ -48,7 +90,7 @@ namespace MudServer
Console.Write(Log.GetMessages());
Log.FlushMessages();
System.Threading.Thread.Sleep(1);
}
*/
}
}
}

View file

@ -6,4 +6,16 @@ MudServer.pdb
MudServer.vshost.exe
MudServer.vshost.exe.manifest
startup.dat
</Value></Property><Property><Name>svn:ignore</Name><Value>Log.txt
MudEngine.dll
MudEngine.pdb
MudServer.exe
MudServer.pdb
MudServer.vshost.exe
MudServer.vshost.exe.manifest
Player
Scripts.dll
Settings.ini
startup.dat
temp
</Value></Property></Properties></ItemProperties>

View file

@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Properties><Property><Name>svn:mime-type</Name><Value>application/octet-stream</Value></Property></Properties></ItemProperties>

View file

@ -0,0 +1,7 @@
public class MyGame : Game
{
public MyGame() :base()
{
GameTitle = "Mud Designer Demo Game";
}
}