MudEngine:

- Game now checks to see if there is a initial environment setup, if not an Abyss is created to store players in.
 - Game now compiles scripts prior to loading libary assemblies to ensure the latest assembly is loaded.
 - BaseCharacter now supports the Abyss room if no initial Game realm is set.
 - BaseCharacter will no longer load the player into a room that does not exist (was deleted or something), they are defaulted into the Abyss.
 - ScriptEngine checks for errors in the script prior to trying to reference the compiled assembly (was causing errors if scripts failed to compile; no assembly generated to reference)
 - Assembly libraries are now only loaded once.

MudServer:
 - Example MyGame.cs script now constructs a realm and sets default properties.
 - MyPlayer script added to show how to write your own player script.
 - Server loop restored and now working correctly.
 - Server now outputs additional info regarding startup.
 - Server now forces TCP protocol.
This commit is contained in:
Scionwest_cp 2010-08-05 19:07:12 -07:00
parent c3c2d22ec7
commit 88378584ac
11 changed files with 199 additions and 30 deletions

View file

@ -1,4 +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:ignore</Name><Value>Mud Designer ToolKit.jpeg
MudDesigner.suo
Design Document.gdp
</Value></Property><Property><Name>svn:mime-type</Name><Value>application/octet-stream</Value></Property></Properties></ItemProperties>

View file

@ -1,4 +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:ignore</Name><Value>Mud Designer ToolKit.jpeg
MudDesigner.suo
Design Document.gdp
</Value></Property><Property><Name>svn:mime-type</Name><Value>application/octet-stream</Value></Property></Properties></ItemProperties>

Binary file not shown.

Binary file not shown.

View file

@ -21,7 +21,18 @@ namespace MudEngine.Commands
string path = player.ActiveGame.DataPaths.Players; string path = player.ActiveGame.DataPaths.Players;
string filename = Path.Combine(path, player.Filename); string filename = Path.Combine(path, player.Filename);
player.Save(filename); //Temporary hack
if (player.ActiveGame.PlayerCollection.Length != 0)
{
if (player.ActiveGame.PlayerCollection[0].GetType().Name != "BaseCharacter")
{
Scripting.GameObject obj = player.ActiveGame.scriptEngine.GetObject(player.ActiveGame.PlayerCollection.GetType().Name);
obj.InvokeMethod("Save", new object[] { player.Name });
}
}
else
player.Save(filename); //Should never be called?
return new CommandResults(); return new CommandResults();
} }

View file

@ -177,7 +177,7 @@ namespace MudEngine.GameManagement
/// <summary> /// <summary>
/// Collection of players currently running on the server. /// Collection of players currently running on the server.
/// </summary> /// </summary>
internal BaseCharacter[] PlayerCollection; public BaseCharacter[] PlayerCollection;
/// <summary> /// <summary>
/// Gets the current running Server object. /// Gets the current running Server object.
@ -237,8 +237,12 @@ namespace MudEngine.GameManagement
public bool Start() public bool Start()
{ {
Log.Write("Game Initializing..."); Log.Write("Game Initializing...");
//First, compile and execute all of the script files.
scriptEngine.ScriptType = ScriptEngine.ScriptTypes.SourceFiles;
scriptEngine.Initialize();
//Setup the scripting engine and load our script library //Next, load any pre-compiled libraries.
scriptEngine.ScriptType = ScriptEngine.ScriptTypes.Assembly;
scriptEngine.Initialize(); scriptEngine.Initialize();
/* /*
@ -274,7 +278,8 @@ namespace MudEngine.GameManagement
if ((InitialRealm == null) || (InitialRealm.InitialZone == null) || (InitialRealm.InitialZone.InitialRoom == null)) if ((InitialRealm == null) || (InitialRealm.InitialZone == null) || (InitialRealm.InitialZone.InitialRoom == null))
{ {
Log.Write("ERROR: No initial location defined. Game startup failed!"); Log.Write("ERROR: No initial location defined. Game startup failed!");
return false; Log.Write("Players will start in the Abyss. Each player will contain their own instance of this room.");
//return false;
} }
else else
Log.Write("Initial Location loaded-> " + InitialRealm.Name + "." + InitialRealm.InitialZone.Name + "." + InitialRealm.InitialZone.InitialRoom.Name); Log.Write("Initial Location loaded-> " + InitialRealm.Name + "." + InitialRealm.InitialZone.Name + "." + InitialRealm.InitialZone.InitialRoom.Name);

View file

@ -50,14 +50,21 @@ namespace MudEngine.GameObjects.Characters
/// </summary> /// </summary>
public CommandEngine CommandSystem { get; internal set; } public CommandEngine CommandSystem { get; internal set; }
public BaseCharacter(Game game)// : base(game) public BaseCharacter(Game game) : base(game)
{ {
ActiveGame = game; ActiveGame = game;
IsActive = false; IsActive = false;
if ((game.InitialRealm == null) || (game.InitialRealm.InitialZone == null) || (game.InitialRealm.InitialZone.InitialRoom == null))
{
CurrentRoom = new Room(game);
CurrentRoom.Name = "Abyss";
CurrentRoom.Description = "You are currently in the abyss.";
}
else
CurrentRoom = game.InitialRealm.InitialZone.InitialRoom; CurrentRoom = game.InitialRealm.InitialZone.InitialRoom;
Inventory = new Bag(game); Inventory = new Bag(game);
CommandSystem = new CommandEngine(); CommandSystem = new CommandEngine();
} }
public override void Load(string filename) public override void Load(string filename)
@ -83,8 +90,27 @@ namespace MudEngine.GameObjects.Characters
//Restore the users current Room. //Restore the users current Room.
Realm realm= ActiveGame.GetRealm(FileManager.GetData(filename, "CurrentRealm")); Realm realm= ActiveGame.GetRealm(FileManager.GetData(filename, "CurrentRealm"));
if (realm == null)
{
realm = new Realm(ActiveGame);
return;
}
Zone zone = realm.GetZone(FileManager.GetData(filename, "CurrentZone")); Zone zone = realm.GetZone(FileManager.GetData(filename, "CurrentZone"));
if (zone == null)
{
zone = new Zone(ActiveGame);
return;
}
CurrentRoom = zone.GetRoom(FileManager.GetData(filename, "CurrentRoom")); CurrentRoom = zone.GetRoom(FileManager.GetData(filename, "CurrentRoom"));
if (CurrentRoom == null)
{
CurrentRoom = new Room(ActiveGame);
CurrentRoom.Name = "Abyss";
CurrentRoom.Description = "You are in the Aybss. It is void of all life.";
return;
}
} }
public override void Save(string filename) public override void Save(string filename)
@ -177,6 +203,13 @@ namespace MudEngine.GameObjects.Characters
ExecuteCommand("Login"); ExecuteCommand("Login");
//Set the players initial room //Set the players initial room
if ((ActiveGame.InitialRealm == null) || (ActiveGame.InitialRealm.InitialZone == null) || (ActiveGame.InitialRealm.InitialZone.InitialRoom == null))
{
CurrentRoom = new Room(ActiveGame);
CurrentRoom.Name = "Abyss";
CurrentRoom.Description = "You are in the Abyss. It is dark and void of life.";
}
else
CurrentRoom = ActiveGame.InitialRealm.InitialZone.InitialRoom; CurrentRoom = ActiveGame.InitialRealm.InitialZone.InitialRoom;
} }
internal void Receive(string data) internal void Receive(string data)

View file

@ -79,7 +79,7 @@ namespace MudEngine.Scripting
} }
} }
private ScriptTypes _ScriptTypes; internal ScriptTypes ScriptType { get; set; }
private Assembly _ScriptAssembly; private Assembly _ScriptAssembly;
private List<Assembly> _AssemblyCollection; private List<Assembly> _AssemblyCollection;
private string[] _ErrorMessages; private string[] _ErrorMessages;
@ -98,7 +98,7 @@ namespace MudEngine.Scripting
public ScriptEngine(Game game, ScriptTypes scriptTypes) public ScriptEngine(Game game, ScriptTypes scriptTypes)
{ {
//Initialize our engine fields //Initialize our engine fields
_ScriptTypes = scriptTypes; ScriptType = scriptTypes;
ScriptExtension = ".cs"; ScriptExtension = ".cs";
//Get our current install path //Get our current install path
@ -133,7 +133,7 @@ namespace MudEngine.Scripting
Directory.CreateDirectory("temp"); Directory.CreateDirectory("temp");
//Setup the additional sourcecode that's needed in the script. //Setup the additional sourcecode that's needed in the script.
string[] usingStatements = new string[] { "using System;", "using MudEngine.GameObjects;", "using MudEngine.GameObjects.Characters;", "using MudEngine.GameManagement;", "using MudEngine.FileSystem;" }; string[] usingStatements = new string[] { "using System;", "using MudEngine.GameObjects;", "using MudEngine.GameObjects.Characters;", "using MudEngine.GameObjects.Environment;", "using MudEngine.GameObjects.Items;", "using MudEngine.GameManagement;", "using MudEngine.FileSystem;", "using MudEngine.Scripting;" };
foreach (string script in scripts) foreach (string script in scripts)
{ {
@ -165,7 +165,7 @@ namespace MudEngine.Scripting
CompilerParameters param = new CompilerParameters(new string[] {"mscorlib.dll", "System.dll", "MudEngine.dll"}); CompilerParameters param = new CompilerParameters(new string[] {"mscorlib.dll", "System.dll", "MudEngine.dll"});
param.GenerateExecutable = false; param.GenerateExecutable = false;
param.GenerateInMemory = true; param.GenerateInMemory = true;
param.OutputAssembly = "Scripts.dll"; param.OutputAssembly = Path.Combine(oldPath, "Scripts.dll");
param.IncludeDebugInformation = false; param.IncludeDebugInformation = false;
param.TreatWarningsAsErrors = true; param.TreatWarningsAsErrors = true;
@ -178,7 +178,6 @@ namespace MudEngine.Scripting
//Delete the temp folder //Delete the temp folder
//Directory.Delete("temp", true); //Directory.Delete("temp", true);
ScriptPath = oldPath; ScriptPath = oldPath;
_ScriptAssembly = results.CompiledAssembly;
//if we encountered errors we need to log them to our ErrorMessages property //if we encountered errors we need to log them to our ErrorMessages property
if (results.Errors.Count >= 1) if (results.Errors.Count >= 1)
@ -196,7 +195,10 @@ namespace MudEngine.Scripting
return false; return false;
} }
else else
{
_ScriptAssembly = results.CompiledAssembly;
return true; return true;
}
#endif #endif
} }
@ -206,7 +208,7 @@ namespace MudEngine.Scripting
/// <param name="scriptAssembly"></param> /// <param name="scriptAssembly"></param>
public void Initialize() public void Initialize()
{ {
if (_ScriptTypes == ScriptTypes.Assembly) if (ScriptType == ScriptTypes.Assembly)
{ {
Log.Write("Loading Assembly based scripts..."); Log.Write("Loading Assembly based scripts...");
InitializeAssembly(); InitializeAssembly();
@ -234,7 +236,7 @@ namespace MudEngine.Scripting
{ {
GameObject obj = new GameObject(Activator.CreateInstance(t, new object[] {_Game}), t.Name); GameObject obj = new GameObject(Activator.CreateInstance(t, new object[] {_Game}), t.Name);
GameObjects.Add(obj); GameObjects.Add(obj);
obj.GetProperty().CurrentRoom = _Game.InitialRealm.InitialZone.InitialRoom; //obj.GetProperty().CurrentRoom = _Game.InitialRealm.InitialZone.InitialRoom;
Log.Write(t.Name + " script loaded."); Log.Write(t.Name + " script loaded.");
continue; continue;
} }
@ -245,6 +247,7 @@ namespace MudEngine.Scripting
} }
} }
} }
_AssemblyCollection.Clear();
} }
private void InitializeAssembly() private void InitializeAssembly()
@ -264,6 +267,19 @@ namespace MudEngine.Scripting
foreach (string library in libraries) foreach (string library in libraries)
{ {
bool isOK = true;
foreach (Assembly assembly in _AssemblyCollection)
{
if (assembly.ManifestModule.ScopeName == Path.GetFileName(library))
{
isOK = false;
break;
}
}
if (!isOK)
continue;
Log.Write("Found possible script libary: " + Path.GetFileName(library)); Log.Write("Found possible script libary: " + Path.GetFileName(library));
_AssemblyCollection.Add(Assembly.LoadFile(library)); _AssemblyCollection.Add(Assembly.LoadFile(library));
} }
@ -280,7 +296,15 @@ namespace MudEngine.Scripting
return; return;
} }
CompileScripts(); if (!CompileScripts())
{
Log.Write("Error Compiling Scripts:");
foreach (string error in _ErrorMessages)
{
Log.Write("Error: " + error);
}
}
else
_AssemblyCollection.Add(_ScriptAssembly); _AssemblyCollection.Add(_ScriptAssembly);
} }

View file

@ -37,9 +37,12 @@ namespace MudServer
scriptEngine.Initialize(); scriptEngine.Initialize();
GameObject obj = scriptEngine.GetObjectOf("Game"); GameObject obj = scriptEngine.GetObjectOf("Game");
Log.Write(Log.GetMessages());
Log.FlushMessages();
if (obj == null) if (obj == null)
{ {
Log.Write("Setting up the Engine Game Manager...");
game = new Game(); game = new Game();
obj = new GameObject(game, "Game"); obj = new GameObject(game, "Game");
scriptEngine = new ScriptEngine((Game)obj.Instance, ScriptEngine.ScriptTypes.Assembly); scriptEngine = new ScriptEngine((Game)obj.Instance, ScriptEngine.ScriptTypes.Assembly);
@ -49,11 +52,23 @@ namespace MudServer
game = (Game)obj.Instance; game = (Game)obj.Instance;
scriptEngine = new ScriptEngine(game, ScriptEngine.ScriptTypes.Assembly); scriptEngine = new ScriptEngine(game, ScriptEngine.ScriptTypes.Assembly);
} }
scriptEngine.ScriptPath = FileManager.GetDataPath(SaveDataTypes.Root);
//Force TCP
game.ServerType = ProtocolType.Tcp;
scriptEngine.Initialize(); //Setup the scripting engine and load our script library
//MUST be called before game.Start()
//scriptEngine.Initialize();
//game.scriptEngine = scriptEngine; //Pass this script engine off to the game to use now.
Console.WriteLine(game.GameTitle); game.Start();
Console.ReadKey();
while (game.IsRunning)
{
Console.Write(Log.GetMessages());
Log.FlushMessages();
System.Threading.Thread.Sleep(1);
}
/* /*

View file

@ -2,6 +2,67 @@ public class MyGame : Game
{ {
public MyGame() :base() public MyGame() :base()
{ {
GameTitle = "Mud Designer Demo Game"; AutoSave = true;
BaseCurrencyName = "Copper";
BaseCurrencyAmount = 1;
CompanyName = "Mud Designer";
DayLength = 60 * 8;
GameTitle = "Test Mud Project";
HideRoomNames = false;
PreCacheObjects = true;
ProjectPath = FileManager.GetDataPath(SaveDataTypes.Root);
TimeOfDay = TimeOfDayOptions.Transition;
TimeOfDayTransition = 30;
Version = "0.1";
Website = "http://MudDesigner.Codeplex.com";
ServerPort = 555;
MaximumPlayers = 1000;
ConstructRealm();
PlayerCollection = new MyPlayer[MaximumPlayers];
}
void ConstructRealm()
{
//Instace our Realm
Realm realm = new Realm(this);
//Set it up.
realm.Name = "Zeroth";
realm.Description = "The land of " + realm.Name + " is fully of large forests and dangerous creatures.";
realm.IsInitialRealm = true;
//Add it to the Base Games Realm Collection
this.AddRealm(realm);
//Build Zones
Zone zone = new Zone(this);
zone.Name = "Home";
zone.Description = "Your home is small and does not contain many items, but it's still your home and someplace you can relax after your battles.";
zone.IsSafe = true;
zone.StatDrain = false;
zone.IsInitialZone = true;
zone.Realm = realm.Name;
realm.AddZone(zone);
Room bedroom = new Room(this);
bedroom.Name = "Bedroom";
bedroom.DetailedDescription.Add("This is your bedroom, it's small but comfortable. You have a bed, a book shelf and a rug on the floor.");
bedroom.DetailedDescription.Add("You may walk to the WEST to find you Closet.");
bedroom.Zone = zone.Name;
bedroom.Realm = realm.Name;
bedroom.IsInitialRoom = true;
zone.AddRoom(bedroom);
Room closet = new Room(this);
closet.Name = "Closet";
closet.DetailedDescription.Add("Your closet contains clothing and some shoes.");
closet.DetailedDescription.Add("You may walk to your EAST to find your Room.");
closet.Zone = zone.Name;
closet.Realm = realm.Name;
zone.AddRoom(closet);
zone.LinkRooms(AvailableTravelDirections.West, closet, bedroom);
} }
} }

View file

@ -0,0 +1,28 @@
public class MyPlayer : BaseCharacter
{
//Example use of custom properties
public string GuildName { get; set; }
//Player constructor. Passes the game parameter off to the parent class BaseCharacter.
public MyPlayer(Game game) : base(game)
{
GuildName = "MUD Guild";
}
public override void Save(string filename)
{
Log.Write("Saving custom player...");
//Don't save if the file name doesn't exist!
if (String.IsNullOrEmpty(filename))
return;
Log.Write("Saving base player...");
//Save all of the parent properties such as character name first.
base.Save(filename);
Log.Write("Saving custom content...");
//Write our GuildName out to the player save file.
FileManager.WriteLine(filename, GuildName, "GuildName");
}
}