WCell Addons

From WCell Wiki

Jump to: navigation, search

Contents

Introduction

WCell uses Addons to extend customization. These Addons are external libraries and are completely separate from the core itself. They are limited only by your own imagination. Using WCell's powerful API, you can do absolutely anything while keeping the core itself untouched. You can easily declare new quests/npcs or hook up to the base steps of the corresponding server. Addons are event driven. Nearly every major step and procedure triggers an event. Addons can be written in any .NET supported language such as: C#, F#, VB, etc.

Usage

  • Both, RealmServer and AuthServer, are capable of loading .NET DLLs (so called Assemblies) at startup and during runtime
  • Addons can currently not be un-loaded or re-loaded, after they have been loaded the first time
  • All .dll files within the AddonFolder and its sub folders (by default Run/<server>/AddonBin/) are automatically attempted to be loaded when the server starts
  • You can specify that you want to exclude certain files or folders by adding them to your Config.xml:
    • IgnoredAddonFiles is a string of files and folders to be ignored, seperated by semicolon (;)
  • There are two types of Assemblies that can be loaded:
    • Actual Addons that have one class that implements IWCellAddon and can have a configuration and whose global variables can be manipulated at runtime
    • Library files that are used by actual Addons and cannot be configured or manipulated at runtime

Creating Addons

Setup

This guide shows how to create an addon, step by step. We will be using Visual C# Express Edition as our IDE because it is powerful, free and easy to use for every beginner.

PROTIP: Usually you want to create a new solution for every Addon and add all of WCell's projects that you will use (except for maybe WCell.Constants) to it.

Creating a new project

  1. Create a new Project
    1. Choose Class Library
    2. Name it whatever you want
    3. Choose to place it in WCell's /Addons folder
    4. Solution: Create new Solution
    5. Uncheck Create directory for solution
  2. Add references
    1. Add the following WCell projects - WCell.Core,WCell.Constants,WCell.RealmServer,WCell.Util.
    2. Expand the references block
    3. Right click on references
    4. Choose the Projects tab and select WCell.Core, WCell.Constants, WCell.RealmServer, WCell.Util and anything else that you might need/want
  3. Set Copy Local of all WCell*, NHibernate, ActiveRecord, logging references and all other references that are part of the WCell core, to False!
  4. Set the Output Path
    1. Right-click your Addon project in the Solution Explorer and select Properties
    2. Go to the Build tab
    3. Set Output Path to: ..\..\Run\<Build Mode>\RealmServerAddons\ - Replacing <Build Mode> with either Debug or Release for the respective configurations

Coding

How to develop a WCell-Addon

Implementing IWCellAddon

NOTE: This can be a a completely standalone class, containing no other code than the implementation of WCellAddonBase members.

Initialization

		[Initialization(InitializationPass.Second)]
		public static void FixConeOfCold()
		{
			// Cone of cold is missing Range
			SpellLineId.MageConeOfCold.Apply(spell =>
			{
				spell.Range.MaxDist = 10;
			});
		}

		[Initialization]
		[DependentInitialization(typeof(GOMgr))]
		public static void InitGOs()
		{
                    // do something to GOs
		}

		[Initialization]
		[DependentInitialization(typeof(NPCMgr))]
		[DependentInitialization(typeof(ItemMgr))]
		public static void InitNPCs()
		{
		    // do something to NPCs and Items
		}

NOTE: These methods can be declared in any public Type, as far as it still is a part of the Addon's project and has the aforementioned attribute.

Add content

Addon Configuration

  • Addons have been hooked up to the same configuration system both RealmServer and AuthServer are using.
  • If you want an Addon with a configuration file, declare UseConfig true in the class which implements WCellAddonBase.
       public override bool UseConfig
       {
           get { return true; }
       }
  • If you want certain fields or properties to be configurable, declare it public static and the value in your code will be the default value.
  • The field or parameter can be string, any enum type, primitive type, or array or IList<T> of such
  • An example of 4 nodes: an int, a boolean, a string and an enum:
       public static int ReConnectWaitTimer = 5;
       public static bool ReJoinOnKick = true;
       public static string WCellCmdPrefix = "#";
       public static IrcCmdCallingRange IrcCmdCallingRange = IrcCmdCallingRange.LocalChannel;
  • Properties can be configurable as well:
       public static int SendQueue
       {
           get { return ThrottledSendQueue.CharsPerSecond; }
           set { ThrottledSendQueue.CharsPerSecond = value; }
       }

Changing the Configuration during runtime

See Configuration

An Example Addon

using System.Globalization;

using WCell.Core.Addons;

using WCell.RealmServer.Spells;
using WCell.RealmServer.Entities;
using WCell.Constants.Spells;
using WCell.Core.Initialization;
using WCell.RealmServer.Chat;
using WCell.Util.Graphics;

namespace WCell.Addons
{
	/// <summary>
	/// WCell's own default addon. Contains some useful additions to the WCell RealmServer that should not be part of the Core.
	/// </summary>
	public class DefaultAddon : WCellAddonBase
	{
		public const SpellId TeleSpellId = //SpellId.UnusedNPCPORTTEST;
			SpellId.UnusedDistractTest;

		public override bool UseConfig
		{
			get { return true; }
		}

		#region WCellAddon Members
		public override string Name
		{
			get { return "WCell Default Addon"; }
		}

		public override string ShortName
		{
			get { return "Default"; }
		}

		public override string Author
		{
			get { return "The WCell Team"; }
		}

		public override string Website
		{
			get { return "http://wcell.org"; }
		}

		public override string GetLocalizedName(CultureInfo culture)
		{
			return "WCell Default Addon";
		}

		public override void TearDown()
		{
			// does nothing
		}

		/// <summary>
		/// Add something to the Last Initialization-Step, so that WCell is already fully initialized before this method is called.
		/// </summary>
		[Initialization(InitializationPass.Last, "Initialize Default Addon")]
		public static void Init()
		{
			// Make some deprecated spell (with an area target) an instant teleport spell:
			SpellHandler.Get(TeleSpellId).SpecialCast = delegate(Spell spell, WorldObject caster, WorldObject target, ref Vector3 targetPos)
			{
				if (caster is Unit)
				{
					var unitCaster = caster as Unit;
					unitCaster.TeleportTo(unitCaster.Region, ref targetPos);
				}
			};

			// add the spell to any newly created staff-Character
			Character.Created += chr =>
			{
				if (chr.Account.Role.IsStaff)
				{
					chr.Spells.Add(TeleSpellId);
				}
			};

			// let staff members join the staff channel
			Character.LoggedIn += (chr, firstConnect) =>
			{
				if (firstConnect)
				{
					if (chr.Account.Role.IsStaff && ChatChannel.Staff != null)
					{
						chr.AddMessage(() => ChatChannel.Staff.TryJoin(chr));
					}
				}
			};
		}
		#endregion
	}
}

Community

Personal tools