I'm not going to help with any issues that you got if you do not want to put any effort into it yourself.
This is a much newer version than the previous released version of ProjectX V3.
It uses MSSQL for almost everything, however this version does not use mssql for the items/equips, it was before I made that. The tables for it have been added in the database so you could go ahead and do it yourself.
I hope this project will be useful to some.
A lot of credits goes to pro4never and the Albetros source.
Client patch: 5515+ (Was developed at 5517)
Download: (Contains the source + database)

FAQ
What is ProjectX?
It was a server that me, Psychodelic and Sedat was working on, but eventually has quit as of now. I might release a few things for the source, but do not expect anything, but the released source. The released source is not the full version or the up to date, but an older backup that I fixed up a bit before releasing.
What patch does the source work at?
5515+ (Was developed at 5517 and might work at patches like 5500+ and up to like 5550?)
How do I install the server?
Look the installation guide.
How can I get a client?
Look here:

Some features are not working, how can I get them to work?
You would need to code them. This is not a plug n' play server.
How can I remove/edit the AI Bots sitting around the server?
Open the game database and then DB_BotInfo. Delete all the entries.
How can I edit the gear AI bots sitting around the server uses?
Open the game database and then DB_Bots.
How can I add/edit npcs?
Go to CODB\game\NPCScripts. There is already examples added.
Some items does not work, how can I add them?
Go to CODB\game\ItemScripts. The concept is the same as npc scripts.
How can I make myself GM?
Open DB_Players and edit the PlayerPermission column.
Permissions are:
PM
GM
Mod
Normal
Banned
How can I edit NPC spawns or names?
Open DB_NPCInfo in the game database.
How can I load NPC's dynamic so I won't need to compile all the times?
You could either make some thread check whether the files has changed or you can make a command to load them. All you have to do is call this method:
My client crashes on login, what can I do?
Make sure you're not connecting using a local IP. It has to be an external IP or hamachi IP.
It was a server that me, Psychodelic and Sedat was working on, but eventually has quit as of now. I might release a few things for the source, but do not expect anything, but the released source. The released source is not the full version or the up to date, but an older backup that I fixed up a bit before releasing.
What patch does the source work at?
5515+ (Was developed at 5517 and might work at patches like 5500+ and up to like 5550?)
How do I install the server?
Look the installation guide.
How can I get a client?
Look here:

Some features are not working, how can I get them to work?
You would need to code them. This is not a plug n' play server.
How can I remove/edit the AI Bots sitting around the server?
Open the game database and then DB_BotInfo. Delete all the entries.
How can I edit the gear AI bots sitting around the server uses?
Open the game database and then DB_Bots.
How can I add/edit npcs?
Go to CODB\game\NPCScripts. There is already examples added.
Some items does not work, how can I add them?
Go to CODB\game\ItemScripts. The concept is the same as npc scripts.
How can I make myself GM?
Open DB_Players and edit the PlayerPermission column.
Permissions are:
PM
GM
Mod
Normal
Banned
How can I edit NPC spawns or names?
Open DB_NPCInfo in the game database.
How can I load NPC's dynamic so I won't need to compile all the times?
You could either make some thread check whether the files has changed or you can make a command to load them. All you have to do is call this method:
Code:
Core.Kernel.ScriptEngine.Check_Updates();
Make sure you're not connecting using a local IP. It has to be an external IP or hamachi IP.
Fixes / Optimizations

Fix attack experiences
This is quite some work, but it's necessary to make Sobs work at least! So if you plan on using Sobs (Ex. GuildPole, LeftGate, RightGate etc.) then you need to do it.
Under ProjectX_V3_Game\Packets\Interaction\Battle you have to change something in these files:
You have to find a line similar to this:
Which wraps around some exp. It's named target and targetentity depending on the file.
Make sure you only change it where it wraps around exp code like the one below.
You have to change that one line to:
>> Repeat that process for all the files until only monsters add experience.
Under ProjectX_V3_Game\Packets\Interaction\Battle you have to change something in these files:
Code:
ProjectX_V3_Game\Packets\Interaction\Battle\Skills\ArcherSkills.cs ProjectX_V3_Game\Packets\Interaction\Battle\Skills\CircleSkills.cs ProjectX_V3_Game\Packets\Interaction\Battle\Skills\LineSkills.cs ProjectX_V3_Game\Packets\Interaction\Battle\Skills\NinjaSkills.cs ProjectX_V3_Game\Packets\Interaction\Battle\Skills\ScatterSkills.cs ProjectX_V3_Game\Packets\Interaction\Battle\Skills\SectorSkills.cs ProjectX_V3_Game\Packets\Interaction\Battle\Skills\Single.cs ProjectX_V3_Game\Packets\Interaction\Battle\Physical.cs ProjectX_V3_Game\Packets\Interaction\Battle\Ranged.cs
Code:
if (!(targetentity is Entities.GameClient))
Make sure you only change it where it wraps around exp code like the one below.
Code:
Code:
if ((targetentity is Entities.Monster))
Fix NPC scripts
After stripping some things away from the source then NPC scripts has broken.
To fix this follow these steps.
1. Open CODB\NPCScripts\DuelMaster.cs
2. Find:
3. Change it to:
To fix this follow these steps.
1. Open CODB\NPCScripts\DuelMaster.cs
2. Find:
Code:
bot.LoadBot(ProjectX_V3_Game.Enums.BotType.DuelBot, client.Server, 0, new MapPoint(client.Map.MapID, client.X, client.Y), client);
Code:
bot.LoadBot(ProjectX_V3_Game.Enums.BotType.DuelBot, 0, new MapPoint(client.Map.MapID, client.X, client.Y), client);
Optimized Script Engine (Uses FileSystemWatcher for updating.)
1. Replace ScriptEngine.cs in ProjectX_V3_Lib with this:
Replace ScriptDatabase.cs in ProjectX_V3_Game with this:
Code:
//Project by BaussHacker aka. L33TS
using System;
using System.Text;
using System.Linq;
using Microsoft.CSharp;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.VisualBasic;
using System.Collections.Generic;
using System.IO;
using System.Security.Permissions;
namespace ProjectX_V3_Lib.ScriptEngine
{
/// <summary>
/// Description of ScriptEngine.
/// </summary>
public class ScriptEngine
{
/// <summary>
/// The settings associated with the script engine.
/// </summary>
private ScriptSettings Settings;
/// <summary>
/// The interval between each script update.
/// </summary>
private int checkInterval;
/// <summary>
/// Creates a new instance of ScriptEngine.
/// </summary>
/// <param name="Settings">The settings associated to the script engine.</param>
/// <param name="scriptcheckinterval">The interval between each script update.</param>
public ScriptEngine(ScriptSettings Settings, int scriptcheckinterval)
{
this.checkInterval = scriptcheckinterval;
this.Settings = Settings;
scriptCollection = new ScriptCollection(Settings);
}
public static void SetNamespaces(ScriptSettings settings)
{
Content = Content.Replace("__namespace__", getns(settings));
Content2 = Content2.Replace("__namespace__", getns2(settings));
}
[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
public void Run()
{
UpdateScripts();
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = this.Settings.ScriptLocation;
watcher.Filter = "*.cs";
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName;
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
watcher.EnableRaisingEvents = true;
}
private void OnChanged(object source, FileSystemEventArgs e)
{
UpdateScripts();
}
private void OnRenamed(object source, RenamedEventArgs e)
{
UpdateScripts();
}
/// <summary>
/// The c# code content.
/// </summary>
private static string Content = @"__namespace__
namespace scriptnamespace
{
class scriptclass
{
__method__
}
}";
/// <summary>
/// The vb code content.
/// </summary>
private static string Content2 = @"__namespace__
Namespace scriptnamespace
Class scriptclass
__method__
End Class
End Namespace";
/// <summary>
/// Gets the namespace code for c#.
/// </summary>
/// <returns>Returns the namespace code.</returns>
private static string getns(ScriptSettings Settings)
{
StringBuilder namespaceBuilder = new StringBuilder();
foreach (string _namespace in Settings._namespaces.Values)
{
namespaceBuilder.Append("using ").Append(_namespace).Append(";").Append(Environment.NewLine);
}
return namespaceBuilder.ToString();
}
/// <summary>
/// Gets the namespace code for vb.
/// </summary>
/// <returns>Returns the namespace code.</returns>
private static string getns2(ScriptSettings Settings)
{
StringBuilder namespaceBuilder = new StringBuilder();
foreach (string _namespace in Settings._namespaces.Values)
{
namespaceBuilder.Append("Imports ").Append(_namespace).Append(Environment.NewLine);
}
return namespaceBuilder.ToString();
}
private string currentcompilefile;
/// <summary>
/// Checks for updates.
/// </summary>
private void UpdateScripts()
{
try
{
foreach (string file in System.IO.Directory.GetFiles(Settings.ScriptLocation + "\\cmpl"))
{
try
{
System.IO.File.Delete(file);
}
catch { } // no permission
}
DateTime now = DateTime.Now;
currentcompilefile = "\\cmpl\\cmpl_" + now.Month + "-" + now.Day + "-" + now.Hour + "-" + now.Minute + "-" + now.Second;
switch (Settings.Language)
{
case ScriptLanguage.CSharp:
{
StringBuilder scriptBuilder = new StringBuilder();
foreach (string file in System.IO.Directory.GetFiles(Settings.ScriptLocation))
{
if (file.EndsWith(".cs"))
{
scriptBuilder.Append(System.IO.File.ReadAllText(file));
scriptBuilder.Append(Environment.NewLine);
}
}
System.IO.File.WriteAllText(Settings.ScriptLocation + currentcompilefile + ".cs", Content.Replace("__method__", scriptBuilder.ToString()));
CompileCSScripts();
break;
}
case ScriptLanguage.VisualBasic:
{
StringBuilder scriptBuilder = new StringBuilder();
foreach (string file in System.IO.Directory.GetFiles(Settings.ScriptLocation))
{
if (file.EndsWith(".vb"))
{
scriptBuilder.Append(System.IO.File.ReadAllText(file));
scriptBuilder.Append(Environment.NewLine);
}
}
System.IO.File.WriteAllText(Settings.ScriptLocation + currentcompilefile + ".vb", Content2.Replace("__method__", scriptBuilder.ToString()));
CompileCSScripts();
break;
}
}
}
catch (Exception e)
{
Console.WriteLine("Script loading failed... Exception: {0}{1}", Environment.NewLine, e.ToString());
}
}
/// <summary>
/// Compiles all the c# scripts.
/// </summary>
private void CompileCSScripts()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("CompilerVersion", Settings.Framework);
CompilerParameters compilerParameters = new CompilerParameters
{
GenerateInMemory = true
};
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Assembly assembly = assemblies[i];
compilerParameters.ReferencedAssemblies.Add(assembly.Location);
}
foreach (string refs in System.IO.Directory.GetFiles(Settings.ScriptLocation + "\\references"))
compilerParameters.ReferencedAssemblies.Add(refs);
foreach (Type type in Settings.types.Values)
compilerParameters.ReferencedAssemblies.Add(Assembly.GetAssembly(type).Location);
CSharpCodeProvider cSharpCodeProvider = new CSharpCodeProvider();
CompilerResults compilerResults = cSharpCodeProvider.CompileAssemblyFromFile(compilerParameters, Settings.ScriptLocation + currentcompilefile + ".cs");
if (compilerResults.Errors.Count != 0)
{
foreach (CompilerError err in compilerResults.Errors)
Console.WriteLine(err.ToString());
}
else
{
foreach (Type type in compilerResults.CompiledAssembly.GetTypes())
{
if (type.Namespace == "scriptnamespace" && type.IsClass && type.Name == "scriptclass")
{
foreach (MethodInfo method in type.GetMethods())
{
if (method.IsStatic)
{
if (method.Name.StartsWith("script_"))
scriptCollection.AddOrUpdate(uint.Parse(method.Name.Split('_')[1]), method);
}
}
}
}
}
}
/// <summary>
/// Compiles all the vb scripts.
/// </summary>
private void CompileVBScripts()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("CompilerVersion", Settings.Framework);
CompilerParameters compilerParameters = new CompilerParameters
{
GenerateInMemory = true
};
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Assembly assembly = assemblies[i];
compilerParameters.ReferencedAssemblies.Add(assembly.Location);
}
foreach (string refs in System.IO.Directory.GetFiles(Settings.ScriptLocation + "\\references"))
compilerParameters.ReferencedAssemblies.Add(refs);
foreach (Type type in Settings.types.Values)
compilerParameters.ReferencedAssemblies.Add(Assembly.GetAssembly(type).Location);
VBCodeProvider vbCodeProvider = new VBCodeProvider();
CompilerResults compilerResults = vbCodeProvider.CompileAssemblyFromFile(compilerParameters, Settings.ScriptLocation + currentcompilefile + ".vb");
if (compilerResults.Errors.Count != 0)
{
foreach (CompilerError err in compilerResults.Errors)
Console.WriteLine(err.ToString());
}
else
{
foreach (Type type in compilerResults.CompiledAssembly.GetTypes())
{
if (type.Namespace == "scriptnamespace" && type.IsClass && type.Name == "scriptclass")
{
foreach (MethodInfo method in type.GetMethods())
{
if (method.IsStatic)
{
if (method.Name.StartsWith("script_"))
scriptCollection.AddOrUpdate(uint.Parse(method.Name.Split('_')[1]), method);
}
}
}
}
}
}
/// <summary>
/// The collection of the scripts.
/// </summary>
private ScriptCollection scriptCollection;
/// <summary>
/// Invokes a script.
/// </summary>
/// <param name="key">The script key.</param>
/// <param name="paramters">Parameters associated with the script. [null, if no parameters]</param>
/// <returns>Returns true if the script exist.</returns>
public bool Invoke(uint key, object[] paramters)
{
return scriptCollection.Invoke(key, paramters);
}
}
}
Code:
//Project by BaussHacker aka. L33TS
using System;
using ProjectX_V3_Lib.ScriptEngine;
using ProjectX_V3_Lib.Extensions;
using System.Linq;
using System.Reflection;
namespace ProjectX_V3_Game.Database
{
/// <summary>
/// Description of ScriptDatabase.
/// </summary>
public class ScriptDatabase
{
private static Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
{
return assembly.GetTypes().Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToArray();
}
public static ScriptSettings cssettings;
/// <summary>
/// Loads the global script settings.
/// </summary>
public static void LoadSettings()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\tLoading Script Settings...");
cssettings = new ScriptSettings();
cssettings.AddNamespace("System");
cssettings.AddNamespace("ProjectX_V3_Game.Entities");
cssettings.AddNamespace("ProjectX_V3_Game.Core");
cssettings.AddNamespace("ProjectX_V3_Game.Data");
cssettings.AddNamespace("ProjectX_V3_Game.Calculations");
cssettings.AddNamespace("ProjectX_V3_Game.Packets.Message");
cssettings.AddNamespace("ProjectX_V3_Game.Packets");
cssettings.AddNamespace("ProjectX_V3_Game.Maps");
cssettings.AddNamespace("ProjectX_V3_Game.Tournaments");
cssettings.AddNamespace("ProjectX_V3_Game.Packets.NPC"); // will add some functions to this later, not entirely npc restricted, but mostly hence why it's also used by ItemScripts!
ScriptEngine.SetNamespaces(cssettings);
cssettings.Framework = "v4.0";
cssettings.Language = ScriptLanguage.CSharp;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\tLoaded Script Settings...");
}
/// <summary>
/// Loads all the npc scripts.
/// </summary>
public static void LoadNPCScripts()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\tLoading NPC Scripts...");
ScriptSettings x = ScriptDatabase.cssettings.DeepClone();
x.ScriptLocation = ServerDatabase.DatabaseLocation + "\\NPCScripts";
x.AddScriptType(typeof(Packets.MessagePacket));
x.AddScriptType(typeof(Packets.Message.MessageCore));
x.AddScriptType(typeof(Packets.NPC.NPCHandler));
x.AddScriptType(typeof(Data.ItemInfo));
x.AddScriptType(typeof(Data.Equipments));
x.AddScriptType(typeof(Data.SpellInfo));
x.AddScriptType(typeof(Data.Spell));
x.AddScriptType(typeof(Data.SpellData));
x.AddScriptType(typeof(Data.Team));
x.AddScriptType(typeof(Data.NobilityBoard));
x.AddScriptType(typeof(Data.NobilityDonation));
x.AddScriptType(typeof(Maps.Map));
x.AddScriptType(typeof(Maps.MapPoint));
x.AddScriptType(typeof(Maps.MapTools));
x.AddScriptType(typeof(Core.Kernel));
x.AddScriptType(typeof(Data.Guild));
x.AddScriptType(typeof(Data.GuildMember));
x.AddScriptType(typeof(Database.CharacterDatabase));
x.AddScriptType(typeof(Calculations.BasicCalculations));
Type[] typelist = GetTypesInNamespace(System.Reflection.Assembly.GetExecutingAssembly(), "ProjectX_V3_Game.Enums");
foreach (Type type in typelist)
x.AddScriptType(type);
Type[] typelist2 = GetTypesInNamespace(System.Reflection.Assembly.GetExecutingAssembly(), "ProjectX_V3_Game.Tournaments");
foreach (Type type in typelist2)
x.AddScriptType(type);
Type[] typelist3 = GetTypesInNamespace(System.Reflection.Assembly.GetExecutingAssembly(), "ProjectX_V3_Game.Entities");
foreach (Type type in typelist3)
x.AddScriptType(type);
Core.Kernel.ScriptEngine = new ScriptEngine(x, Core.TimeIntervals.ScriptUpdate); // scripts updates every 10 sec.
Core.Kernel.ScriptEngine.Run();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\tLoaded NPC Scripts...");
}
/// <summary>
/// Loads all the item scripts.
/// </summary>
public static void LoadItemScripts()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("\tLoading Item Scripts...");
ScriptSettings x = ScriptDatabase.cssettings.DeepClone();
x.ScriptLocation = ServerDatabase.DatabaseLocation + "\\ItemScripts";
x.AddScriptType(typeof(Packets.MessagePacket));
x.AddScriptType(typeof(Packets.Message.MessageCore));
x.AddScriptType(typeof(Packets.NPC.NPCHandler));
x.AddScriptType(typeof(Data.ItemInfo));
x.AddScriptType(typeof(Data.Equipments));
x.AddScriptType(typeof(Data.SpellInfo));
x.AddScriptType(typeof(Data.Spell));
x.AddScriptType(typeof(Data.SpellData));
x.AddScriptType(typeof(Data.Team));
x.AddScriptType(typeof(Data.NobilityBoard));
x.AddScriptType(typeof(Data.NobilityDonation));
x.AddScriptType(typeof(Maps.Map));
x.AddScriptType(typeof(Maps.MapPoint));
x.AddScriptType(typeof(Maps.MapTools));
x.AddScriptType(typeof(Core.Kernel));
x.AddScriptType(typeof(Data.Guild));
x.AddScriptType(typeof(Data.GuildMember));
x.AddScriptType(typeof(Database.CharacterDatabase));
x.AddScriptType(typeof(Calculations.BasicCalculations));
Type[] typelist = GetTypesInNamespace(System.Reflection.Assembly.GetExecutingAssembly(), "ProjectX_V3_Game.Enums");
foreach (Type type in typelist)
x.AddScriptType(type);
Type[] typelist2 = GetTypesInNamespace(System.Reflection.Assembly.GetExecutingAssembly(), "ProjectX_V3_Game.Tournaments");
foreach (Type type in typelist2)
x.AddScriptType(type);
Type[] typelist3 = GetTypesInNamespace(System.Reflection.Assembly.GetExecutingAssembly(), "ProjectX_V3_Game.Entities");
foreach (Type type in typelist3)
x.AddScriptType(type);
Core.Kernel.ItemScriptEngine = new ScriptEngine(x, Core.TimeIntervals.ScriptUpdate); // scripts updates every 10 sec.
Core.Kernel.ItemScriptEngine.Run();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\tLoaded Item Scripts...");
}
}
}
Fixing ArtisanWind
Replace all the code in ProjectX_V3_Game.Packets.Item.Improve.cs with this:
And replace all the code in ProjectX_V3_Game.Packets.Item.Uplev.cs with this:
That's it.
Code:
//Project by BaussHacker aka. L33TS
using System;
namespace ProjectX_V3_Game.Packets.Item
{
/// <summary>
/// Description of Uplev.
/// </summary>
public class Uplev
{
public static void Handle(Entities.GameClient client, ItemPacket packet)
{
if (client.Booth != null)
return;
if (!client.Alive)
return;
if (!client.Inventory.ContainsByUID(packet.UID) && client.Inventory.ContainsByUID(packet.Data1))
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_NOT_FOUND))
client.Send(msg);
return;
}
Data.ItemInfo ToUpgrade = client.Inventory.GetItemByUID(packet.UID);
if (ToUpgrade.CurrentDura < ToUpgrade.MaxDura)
return;
Data.ItemInfo Meteor = client.Inventory.GetItemByUID(packet.Data1);
if (Meteor == null || ToUpgrade == null)
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_NOT_FOUND))
client.Send(msg);
return;
}
if (ToUpgrade.IsGarment() || ToUpgrade.IsArrow() || ToUpgrade.IsBottle() ||
ToUpgrade.IsSteed() || ToUpgrade.IsMisc())
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_INVALID_UPGRADE))
client.Send(msg);
return;
}
if (ToUpgrade.RequiredLevel >= 120)
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_MAX_LEVEL))
client.Send(msg);
return; // max level
}
if (Meteor.ItemID != 1088001 && Meteor.ItemID != 1088002)
{
using (var msg = Packets.Message.MessageCore.CreateSystem(
client.Name,
string.Format(Core.MessageConst.ITEM_AMOUNT_FAIL, "Meteor- or Meteortear's")))
client.Send(msg);
return;
}
uint NewID = ToUpgrade.ItemID + 10;
int loop = 4;
while (!Core.Kernel.ItemInfos.Contains(NewID))
{
NewID += 10;
loop--;
if (loop <= 0)
break;
}
if (Core.Kernel.ItemInfos.Contains(NewID))
{
Data.ItemInfo newItem;
if (Core.Kernel.ItemInfos.TrySelect(NewID, out newItem))
{
if (newItem.RequiredLevel > ToUpgrade.RequiredLevel && newItem.TypeName == ToUpgrade.TypeName)
{
client.Inventory.RemoveItemByUID(Meteor.UID);
if (Calculations.BasicCalculations.ChanceSuccess(Core.NumericConst.LevelUpgradeChance))
{
Data.ItemInfo NewUpgradedItem = newItem.Copy();
NewUpgradedItem.SetStats(ToUpgrade);
client.Inventory.RemoveItemByUID(ToUpgrade.UID);
if (Calculations.BasicCalculations.ChanceSuccess(Core.NumericConst.FirstSocketChance) &&
NewUpgradedItem.Gem1 == Enums.SocketGem.NoSocket)
{
NewUpgradedItem.Gem1 = Enums.SocketGem.EmptySocket;
}
else if (Calculations.BasicCalculations.ChanceSuccess(Core.NumericConst.SecondSocketChance) &&
NewUpgradedItem.Gem2 == Enums.SocketGem.NoSocket)
{
if (NewUpgradedItem.Gem1 == Enums.SocketGem.EmptySocket)
NewUpgradedItem.Gem2 = Enums.SocketGem.EmptySocket;
}
client.Inventory.AddItem(NewUpgradedItem);
}
}
}
}
}
}
}
Code:
//Project by BaussHacker aka. L33TS
using System;
namespace ProjectX_V3_Game.Packets.Item
{
/// <summary>
/// Description of Uplev.
/// </summary>
public class Uplev
{
public static void Handle(Entities.GameClient client, ItemPacket packet)
{
if (client.Booth != null)
return;
if (!client.Alive)
return;
if (!client.Inventory.ContainsByUID(packet.UID) && client.Inventory.ContainsByUID(packet.Data1))
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_NOT_FOUND))
client.Send(msg);
return;
}
Data.ItemInfo ToUpgrade = client.Inventory.GetItemByUID(packet.UID);
if (ToUpgrade.CurrentDura < ToUpgrade.MaxDura)
return;
Data.ItemInfo Meteor = client.Inventory.GetItemByUID(packet.Data1);
if (Meteor == null || ToUpgrade == null)
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_NOT_FOUND))
client.Send(msg);
return;
}
if (ToUpgrade.IsGarment() || ToUpgrade.IsArrow() || ToUpgrade.IsBottle() ||
ToUpgrade.IsSteed() || ToUpgrade.IsMisc())
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_INVALID_UPGRADE))
client.Send(msg);
return;
}
if (ToUpgrade.RequiredLevel >= 120)
{
using (var msg = Packets.Message.MessageCore.CreateSystem(client.Name, Core.MessageConst.ITEM_MAX_LEVEL))
client.Send(msg);
return; // max level
}
if (Meteor.ItemID != 1088001 && Meteor.ItemID != 1088002)
{
using (var msg = Packets.Message.MessageCore.CreateSystem(
client.Name,
string.Format(Core.MessageConst.ITEM_AMOUNT_FAIL, "Meteor- or Meteortear's")))
client.Send(msg);
return;
}
uint NewID = ToUpgrade.ItemID + 10;
int loop = 4;
while (!Core.Kernel.ItemInfos.Contains(NewID))
{
NewID += 10;
loop--;
if (loop <= 0)
break;
}
if (Core.Kernel.ItemInfos.Contains(NewID))
{
Data.ItemInfo newItem;
if (Core.Kernel.ItemInfos.TrySelect(NewID, out newItem))
{
if (newItem.RequiredLevel > ToUpgrade.RequiredLevel && newItem.TypeName == ToUpgrade.TypeName)
{
client.Inventory.RemoveItemByUID(Meteor.UID);
if (Calculations.BasicCalculations.ChanceSuccess(Core.NumericConst.LevelUpgradeChance))
{
Data.ItemInfo NewUpgradedItem = newItem.Copy();
NewUpgradedItem.SetStats(ToUpgrade);
client.Inventory.RemoveItemByUID(ToUpgrade.UID);
if (Calculations.BasicCalculations.ChanceSuccess(Core.NumericConst.FirstSocketChance) &&
NewUpgradedItem.Gem1 == Enums.SocketGem.NoSocket)
{
NewUpgradedItem.Gem1 = Enums.SocketGem.EmptySocket;
}
else if (Calculations.BasicCalculations.ChanceSuccess(Core.NumericConst.SecondSocketChance) &&
NewUpgradedItem.Gem2 == Enums.SocketGem.NoSocket)
{
if (NewUpgradedItem.Gem1 == Enums.SocketGem.EmptySocket)
NewUpgradedItem.Gem2 = Enums.SocketGem.EmptySocket;
}
client.Inventory.AddItem(NewUpgradedItem);
}
}
}
}
}
}
}
Autoload NPC spawns from DB.
By adding this you will no longer have to restart the server when adding new NPC's in the database.
1. Create a new class in ProjectX_V3_Game.Threads called NPCDBThread.cs
2. Replace everything with this:
3. Open ProjectX_V3_Game.Database.NPCDatabase.cs and replace LoadNPCInfo() with this:
4. Add this to the NPCDatabase class as well.
5. Add this to GlobalThreads.Start().
6. Done. You can now add/remove npcs when the server is already online.
1. Create a new class in ProjectX_V3_Game.Threads called NPCDBThread.cs
2. Replace everything with this:
Code:
//Project by BaussHacker aka. L33TS
using System;
namespace ProjectX_V3_Game.Threads
{
/// <summary>
/// Handling the npc database thread.
/// </summary>
public class NPCDBThread
{
public static void Handle()
{
bool NewCount;
int NPCCount = Database.NPCDatabase.GetNPCCount(out NewCount);
if (NewCount)
{
foreach (Entities.NPC npc in Core.Kernel.NPCs.Values)
{
npc.Map.LeaveMap(npc);
}
Core.Kernel.NPCs.Clear();
int failed;
Core.Kernel.Clients.TryForeachAction((uid, client) => { client.Screen.FullUpdate(); }, out failed);
Database.NPCDatabase.LoadNPCInfo(false);
}
}
}
}
Code:
/// <summary>
/// Loads all the npc informations and spawns.
/// </summary>
/// <returns>Returns true if the the infos/spawns were loaded.</returns>
public static bool LoadNPCInfo(bool display = true)
{
Console.ForegroundColor = ConsoleColor.Yellow;
if (display)
Console.WriteLine("\tLoading NPCs...");
using (var sql = new SqlHandler(Program.Config.ReadString("GameConnectionString")))
{
using (var cmd = new SqlCommandBuilder(sql, SqlCommandType.SELECT, false))
{
cmd.Finish("DB_NPCInfo");
}
while (sql.Read())
{
Entities.NPC npc = new ProjectX_V3_Game.Entities.NPC();
npc.EntityUID = sql.ReadUInt32("NPCID");
ushort mapid = sql.ReadUInt16("MapID");
npc.X = sql.ReadUInt16("X");
npc.Y = sql.ReadUInt16("Y");
if (mapid == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Failed to load npcs. [MAPID]");
Console.ResetColor();
return false;
}
Maps.Map map;
Core.Kernel.Maps.TrySelect(mapid, out map);
npc.Map = map;
if (!npc.Map.EnterMap(npc))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Failed to load npcs. [MAP]");
Console.ResetColor();
return false;
}
npc.Mesh = sql.ReadUInt16("Mesh");
npc.Flag = sql.ReadUInt32("Flag");
npc.Name = sql.ReadString("NPCName");
npc.NPCType = (Enums.NPCType)Enum.Parse(typeof(Enums.NPCType), sql.ReadString("Type"));
npc.Avatar = sql.ReadByte("Avatar");
if (!Core.Kernel.NPCs.TryAdd(npc.EntityUID, npc))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Failed to load npcs. [ADD]");
Console.ResetColor();
return false;
}
}
}
if (display)
{
bool nCount;
int count = GetNPCCount(out nCount);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\tLoaded {0}/{1} NPCs...", Core.Kernel.NPCs.Count, count);
}
return true;
}
Code:
private static int LastCount = 0;
public static int GetNPCCount(out bool NewCount)
{
int count = 0;
NewCount = false;
using (var sql = new System.Data.SqlClient.SqlConnection(Program.Config.ReadString("GameConnectionString")))
{
sql.Open();
using (var cmd = new System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM DB_NPCInfo", sql))
{
count = (int)cmd.ExecuteScalar();
}
}
if (LastCount != count)
NewCount = true;
LastCount = count;
return count;
}
Code:
new BaseThread(NPCDBThread.Handle, 5000, "NPCDBThread").Start();
Installation:
Full Guide:
1. Install MSSQL

Note:
You have to download "Microsoft® SQL Server® 2012 Express" and "Microsoft® SQL Server® 2008 Management Studio Express"
2. Move CODB to your root folder, ex. C:\
3. Open CODB\auth\Config.xml and edit the IP for both auth and game.
4. Edit the password (It has to match the password used at the game server.)
5. Edit the ConnectionString's Server (Make sure to remember it from installing, usually it is USERNAME\VERSION.)
6. Do the same in CODB\game\Config.xml
7. Open SQL Management Studio
8. Open "Databases"
9. Right click "Databases" and click "New Database..." - Name it "ProjectX_Auth_Database"
10. Right click "Databases" and click "New Database..." - Name it "ProjectX_Game_Database"
11. Drag "authdb.sql" into SQL Management Studio OR choose to open it with it.
12. Execute the script.
13. Do the same with" gamedb.sql"
14. Open ProjectX_Auth_Database and then the table "DB_Accounts"
15. Make a new account by filling out the data.
16. Open the source by the solution file. "ProjectX_V3.sln"
17. Rebuild it all and run both the auth and game server.
Note: There is currently set a permission for only PM's, but it can be edited in Core\Kernel.cs
Change disallow to 3. You can get the permissions in Enums.PlayerPermission.
You can edit the permission of a character in the database "DB_Players"
18. Now edit the IP in the client ex. LoaderSet.ini if you use Conquerloader V5.
19. Login (You have to disconnect after character creation.)
Note: Use Lucky7 to login with.
Congratulations you've set it up correct.

Note:
You have to download "Microsoft® SQL Server® 2012 Express" and "Microsoft® SQL Server® 2008 Management Studio Express"
2. Move CODB to your root folder, ex. C:\
3. Open CODB\auth\Config.xml and edit the IP for both auth and game.
4. Edit the password (It has to match the password used at the game server.)
5. Edit the ConnectionString's Server (Make sure to remember it from installing, usually it is USERNAME\VERSION.)
6. Do the same in CODB\game\Config.xml
7. Open SQL Management Studio
8. Open "Databases"
9. Right click "Databases" and click "New Database..." - Name it "ProjectX_Auth_Database"
10. Right click "Databases" and click "New Database..." - Name it "ProjectX_Game_Database"
11. Drag "authdb.sql" into SQL Management Studio OR choose to open it with it.
12. Execute the script.
13. Do the same with" gamedb.sql"
14. Open ProjectX_Auth_Database and then the table "DB_Accounts"
15. Make a new account by filling out the data.
16. Open the source by the solution file. "ProjectX_V3.sln"
17. Rebuild it all and run both the auth and game server.
Note: There is currently set a permission for only PM's, but it can be edited in Core\Kernel.cs
Code:
public static bool GotPermission(Enums.PlayerPermission Permission)
{
const byte disallow = 1;
return ((byte)Permission) <= disallow;
}
You can edit the permission of a character in the database "DB_Players"
18. Now edit the IP in the client ex. LoaderSet.ini if you use Conquerloader V5.
19. Login (You have to disconnect after character creation.)
Note: Use Lucky7 to login with.
Congratulations you've set it up correct.
Anyways good luck to whoever uses this.






