[C# - Development] Jolt Environment
Hey
Over the last 2 weeks or so, I've been working on a project called "Jolt Environment", basically a framework for RuneScape, but "Jolt" is an environment, which is powered by MySQL and ION storage, and TCP asynchronous connections. Everything runescape is within the namespace "RuneScape", and everything in Jolt, is not requiring anything from that, so logically, you can basically delete the runescape namespace, and create a emulator of your own usage Jolt
Requirements to Edit / Run:
VS10 with .NET 4.0
MySQL database
Source is well commented for people willing to learn
Connection/NET for MySQL connection is in /Resources/ and also in /Bin/Drivers/ - You don't need to do anything, the emulator automatically loads the drivers for you
You can check out the source & the project @ http://ajravindiran.com/projects/jolt/
Feedback so i can improve :)
Re: [C# - Development] Jolt Environment
Now will this be using the same items and information as the original Runescape or will it be very custimized using the same playingfield?
Re: [C# - Development] Jolt Environment
I will be making it as original as runescape, the server will be really customizable, so it'll be up to the server owner for customization of NPCs, items, objects, and so forth
Re: [C# - Development] Jolt Environment
If you ever think about making it closed source I might be interested in helping out. :)
Re: [C# - Development] Jolt Environment
I've been monitoring this since before he made it public. This is gonna be the most lean framework ever created for RuneScape. Load speeds are incredulously fast, and the asynchronous socket protocol creates more efficiency with less need for looping code. Unlike anything ever released, I highly recommend people start learning this base for future development. If I ever manage, I'll even program for this as well
Re: [C# - Development] Jolt Environment
Re: [C# - Development] Jolt Environment
Quote:
Originally Posted by
jMerliN
Iocp?
Asynchronous .NET sockets inherently use IOCP. This is the .NET framework we're talking about.
Re: [C# - Development] Jolt Environment
Havn't been doing much this week(end), But I've redone the byte vectors (streams).
Isn't really an "improvement", it is basically just more readable, and easier to work with.
CodecFactory.cs:
Code:
/* ######################################## *\
* ### Copyright (C) 2009 AJ Ravindiran ### *
* ### HTTP://THEAJ.NET/ <AJ@THEAJ.NET> ### *
\* ######################################## */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AJRavindiran.Jolt.RuneScape.Network.Codecs
{
/// <summary>
/// Represents a codec factory which controls incoming and outgoing bytevectors.
/// </summary>
public class CodecFactory
{
#region Fields
private int mInputOffset = 0;
private int mInputLength = 0;
private byte[] mInputBuffer;
private int mOutputOffset = 0;
private int mOutputLength = 0;
private byte[] mOutputBuffer;
private int mFrameStackPtr = -1;
private static int mFrameStackSize = 10;
private int[] mFrameStack = new int[mFrameStackSize];
private int[] mBitMaskOut = new int[32];
private int mBitPosition = 0;
#endregion
#region Properties
public int InputOffset
{
get { return mInputOffset; }
set { mInputOffset = value; }
}
public int InputLength
{
get { return mInputLength; }
set { mInputLength = value; }
}
public byte[] InputBuffer
{
get { return mInputBuffer; }
set { mInputBuffer = value; }
}
public int OutputOffset
{
get { return mOutputOffset; }
set { mOutputOffset = value; }
}
public int OutputLength
{
get { return mOutputLength; }
set { mOutputLength = value; }
}
public byte[] OutputBuffer
{
get { return mOutputBuffer; }
set { mOutputBuffer = value; }
}
#endregion
#region Constructors
public CodecFactory(int inputLength, int outputLength)
{
mInputLength = inputLength;
mOutputLength = outputLength;
mInputBuffer = new byte[inputLength];
mOutputBuffer = new byte[outputLength];
for (int i = 0; i < 32; i++)
mBitMaskOut[i] = (1 << i) - 1;
}
#endregion
#region Methods
public byte ReadByte()
{
return (byte)(mInputBuffer[mInputOffset++]);
}
public int ReadSByte()
{
return (ReadByte() & 0xff);
}
public byte ReadByteA()
{
return (byte)(ReadByte() - 128);
}
public byte ReadByteC()
{
return (byte)(-ReadByte());
}
public byte ReadByteS()
{
return (byte)(128 - ReadByte());
}
public int ReadSByteA()
{
return (ReadSByte() - 128 & 0xff);
}
public int ReadSByteC()
{
return -(ReadSByte() & 0xff);
}
public int ReadSByteS()
{
return (128 - ReadSByte() & 0xff);
}
public int Read3Bytes()
{
return (ReadSByte() << 16) | (ReadSByte() << 8) | ReadSByte();
}
public int Read2Bytes()
{
return (ReadSByte() << 8) + ReadSByte();
}
public CodecFactory ReadBytes(byte[] array, int endOffset, int startOffSet)
{
for (int i = startOffSet; i < startOffSet + endOffset; i++)
array[i] = ReadByte();
return this;
}
public CodecFactory ReadBytesReserved(byte[] array, int endOffset, int startOffSet)
{
for (int i = (startOffSet + endOffset) - 1; i >= startOffSet; i--)
array[i] = ReadByte();
return this;
}
public CodecFactory ReadBytesReserved128(byte[] array, int endOffset, int startOffset)
{
for (int i = (startOffset + endOffset) - 1; i >= startOffset; i--)
array[i] = ReadByteA();
return this;
}
public int ReadInt16()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 2] & 0xff) << 8) + (mInputBuffer[mInputOffset - 1] & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadInt16A()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] - 128 & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadInt16Endian()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadInt16EndianA()
{
mInputOffset += 2;
int i = ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] - 128 & 0xff);
if (i > 32767)
i -= 0x10000;
return i;
}
public int ReadUInt16()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] - 128 & 0xff);
}
public int ReadUInt16A()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] - 128 & 0xff);
}
public int ReadUInt16Endian()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] & 0xff);
}
public int ReadUInt16EndianA()
{
mInputOffset += 2;
return ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] - 128 & 0xff);
}
public int ReadInt32()
{
mInputOffset += 4;
return ((mInputBuffer[mInputOffset - 4] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 3] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] & 0xff);
}
public int ReadInt32V1()
{
mInputOffset += 4;
return ((mInputBuffer[mInputOffset - 2] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 1] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 4] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 3] & 0xff);
}
public int ReadInt32V2()
{
mInputOffset += 4;
return ((mInputBuffer[mInputOffset - 3] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 4] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 1] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 2] & 0xff);
}
public long ReadInt64()
{
long l = (long)ReadInt32() & 0xffffffffL;
long l1 = (long)ReadInt32() & 0xffffffffL;
return (l << 32) + l1;
}
public long ReadInt64V2()
{
mInputOffset += 8;
return (((mInputBuffer[mInputOffset - 8] & 0xff) << 56)
+ ((mInputBuffer[mInputOffset - 7] & 0xff) << 48)
+ ((mInputBuffer[mInputOffset - 6] & 0xff) << 40)
+ ((mInputBuffer[mInputOffset - 5] & 0xff) << 32)
+ ((mInputBuffer[mInputOffset - 4] & 0xff) << 24)
+ ((mInputBuffer[mInputOffset - 3] & 0xff) << 16)
+ ((mInputBuffer[mInputOffset - 2] & 0xff) << 8)
+ (mInputBuffer[mInputOffset - 1] & 0xff));
}
public string ReadString()
{
StringBuilder sb = new StringBuilder();
byte b;
while ((b = ReadByte()) != 0)
sb.Append((char)b);
return sb.ToString();
}
public void ExpandOutBuffer()
{
byte[] oldBuffer = mOutputBuffer;
mOutputBuffer = new byte[oldBuffer.Length + 1000];
System.Array.Copy(oldBuffer, 0, mOutputBuffer, 0, oldBuffer.Length);
}
public CodecFactory AppendByte(int i)
{
if (mOutputOffset >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[mOutputOffset++] = (byte)i;
return this;
}
public CodecFactory AppendByte(int i, int position)
{
if (position >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[position] = (byte)i;
return this;
}
public CodecFactory AppendByteA(int i)
{
AppendByte(i + 128);
return this;
}
public CodecFactory AppendByteS(int i)
{
AppendByte(128 - i);
return this;
}
public CodecFactory AppendByteC(int i)
{
AppendByte(-i);
return this;
}
public CodecFactory AppendBytes(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(array[i]);
return this;
}
public CodecFactory AppendBytesS(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(-128 + array[i]);
return this;
}
public CodecFactory AppendBytesA(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(array[i] - 128);
return this;
}
public CodecFactory AppendBytesC(byte[] array, int endOffset, int startOffset)
{
for (int i = startOffset; i < startOffset + endOffset; i++)
AppendByte(array[i] + 128);
return this;
}
public CodecFactory AppendBytesReverse(byte[] array, int endOffset, int startOffset)
{
for (int i = (startOffset + endOffset) - 1; i >= startOffset; i--)
AppendByte(array[i]);
return this;
}
public CodecFactory AppendBytesReverseA(byte[] array, int endOffset, int startOffset)
{
for (int i = (startOffset + endOffset) - 1; i >= startOffset; i--)
AppendByteA(array[i]);
return this;
}
public CodecFactory Append3Byte(int i)
{
AppendByte(i >> 16);
AppendByte(i >> 8);
AppendByte(i);
return this;
}
public CodecFactory AppendInt16(int i)
{
AppendByte(i >> 8);
AppendByte(i);
return this;
}
public CodecFactory AppendInt16A(int i)
{
AppendByte(i >> 8);
AppendByte(i + 128);
return this;
}
public CodecFactory AppendInt16Endian(int i)
{
AppendByte(i);
AppendByte(i >> 8);
return this;
}
public CodecFactory AppendInt16EndianA(int i)
{
AppendByte(i + 128);
AppendByte(i >> 8);
return this;
}
public CodecFactory AppendInt32(int i)
{
AppendByte(i >> 24);
AppendByte(i >> 16);
AppendByte(i >> 8);
AppendByte(i);
return this;
}
public CodecFactory AppendInt32Endian(int i)
{
AppendByte(i);
AppendByte(i >> 8);
AppendByte(i >> 16);
AppendByte(i >> 24);
return this;
}
public CodecFactory AppendInt32V1(int i)
{
AppendByte(i >> 8);
AppendByte(i);
AppendByte(i >> 24);
AppendByte(i >> 16);
return this;
}
public CodecFactory AppendInt32V2(int i)
{
AppendByte(i >> 16);
AppendByte(i >> 24);
AppendByte(i);
AppendByte(i >> 8);
return this;
}
public CodecFactory AppendInt64(long l)
{
AppendByte((int)(l >> 56));
AppendByte((int)(l >> 48));
AppendByte((int)(l >> 40));
AppendByte((int)(l >> 32));
AppendByte((int)(l >> 24));
AppendByte((int)(l >> 16));
AppendByte((int)(l >> 8));
AppendByte((int)l);
return this;
}
public byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
public CodecFactory AppendString(string s)
{
byte[] stringBytes = StrToByteArray(s);
for (int i = 0; i < s.Length; i++)
AppendByte(stringBytes[i]);
AppendByte(0);
return this;
}
public CodecFactory AppendVarByte(int i)
{
if ((i & 255) >= 128)
AppendInt16(i - 32768);
else
AppendByte(i);
return this;
}
public CodecFactory CreateFrame(int id)
{
AppendByteA(id);
return this;
}
public CodecFactory CreateFrameByte(int id)
{
AppendByte(id);
AppendByte(0);
if (mFrameStackPtr >= mFrameStackSize - 1)
JoltEnvironment.GetLogger().WriteWarn("Stack overflow.");
else
mFrameStack[++mFrameStackPtr] = mInputOffset;
return this;
}
public CodecFactory CreateFrameInt16(int id)
{
AppendByte(id);
AppendByte(0);
if (mFrameStackPtr >= mFrameStackSize - 1)
JoltEnvironment.GetLogger().WriteWarn("Stack overflow.");
else
mFrameStack[++mFrameStackPtr] = mInputOffset;
return this;
}
public CodecFactory EndFrameByte()
{
if (mFrameStackPtr < 0)
JoltEnvironment.GetLogger().WriteWarn("Stack empty");
else
AppendFrameSize(mOutputOffset - mFrameStack[mFrameStackPtr--]);
return this;
}
public CodecFactory EndFrameInt16()
{
if (mFrameStackPtr < 0)
JoltEnvironment.GetLogger().WriteWarn("Stack empty");
else
AppendFrameSizeInt16(mOutputOffset - mFrameStack[mFrameStackPtr--]);
return this;
}
public CodecFactory AppendFrameSize(int i)
{
AppendByte(i, (mOutputOffset - i - 1));
return this;
}
public CodecFactory AppendFrameSizeInt16(int i)
{
AppendByte((i >> 8), (mOutputOffset - i - 2));
AppendByte(i, (mOutputOffset - i - 1));
return this;
}
public CodecFactory InitBitAccess()
{
mBitPosition = mOutputOffset * 8;
return this;
}
public CodecFactory FinishBitAccess()
{
mOutputOffset = (mBitPosition + 7) / 8;
return this;
}
public CodecFactory AppendBit(int bit, int pos)
{
if (pos >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[pos] &= (byte)~bit;
return this;
}
public CodecFactory PlaceBit(int bit, int pos)
{
if (pos >= mOutputBuffer.Length)
ExpandOutBuffer();
mOutputBuffer[pos] |= (byte)bit;
return this;
}
public CodecFactory AppendBits(int numBits, int value)
{
int bytePos = mBitPosition >> 3;
int bitOffset = 8 - (mBitPosition & 7);
mBitPosition += numBits;
for (; numBits > bitOffset; bitOffset = 8)
{
AppendBit(mBitMaskOut[bitOffset], bytePos);
PlaceBit(((value >> (numBits - bitOffset)) & mBitMaskOut[bitOffset]), bytePos++);
numBits -= bitOffset;
}
if (numBits == bitOffset)
{
AppendBit(mBitMaskOut[bitOffset], bytePos);
PlaceBit((value & mBitMaskOut[bitOffset]), bytePos);
}
else
{
AppendBit((mBitMaskOut[numBits] << (bitOffset - numBits)), bytePos);
PlaceBit((value & mBitMaskOut[numBits]) << (bitOffset - numBits), bytePos);
}
return this;
}
#endregion
}
}
From the older codec factory you would use the follow code to read / write streams to the runescape client:
Code:
character.GetCodecFactory().GetDecoder().ReadSignedByte();
character.GetCodecFactory().GetDecoder().ReadUnsignedDWord();
character.GetCodecFactory().GetEncoder().WriteByte(0);
character.GetCodecFactory().GetEncoder().WriteDWord(1);
character.GetCodecFactory().GetEncoder().WriteQWord(2);
character.GetCodecFactory().GetEncoder().WriteWord128(3);
character.GetCodecFactory().GetEncoder().WriteUnsignedByte(4);
character.GetCodecFactory().GetEncoder().WriteString("something");
Now:
Code:
character.GetCodecFactory().ReadByte();
character.GetCodecFactory().ReadInt32();
character.GetCodecFactory()
.AppendByte(0)
.AppendInt32(1)
.AppendInt64(2)
.AppendInt16A(3)
.AppendSByte(4)
.AppendString("something");
Re: [C# - Development] Jolt Environment
I suggest you to use SocketAsyncEventArgs in your network code, It's just a more scalable solution created especially for network server applications that require high performance such as a mmorpg server.
http://msdn.microsoft.com/en-us/libr...eventargs.aspx
Re: [C# - Development] Jolt Environment
This looks really nice if you have a beta testing for it i would love to try it.
Re: [C# - Development] Jolt Environment
So its like how mta uses lua, and samp uses pawno?
Re: [C# - Development] Jolt Environment
Added XML parsing yesterday... well, it was already there, but was a temporary placement so i can load some configurations, so basically an improvement. Also updated some old shit, and worked a bit more on character details
Details of the updates:
http://jolte.codeplex.com/SourceCont...leCommits.aspx
http://jolte.codeplex.com/SourceCont...set/view/38372
Example of how i would use the XML before:
Code:
XML config = new XML();
string name = config.ReadValue("config.xml", "server-name");
now:
Code:
string name = "";
JoltEnvironment.GetXML("config").AssignValue("server-name", ref name);
Also can do multiple assignments at once
Code:
string name = "";
string location = "";
string expRate = "";
JoltEnvironment.GetXML("config")
.AssignValue("server-name", ref name)
.AssignValue("default-location", ref location)
.AssignValue("exp-rate", ref expRate);
string[] coords = new string[3];
coords = name.Split(';');
RuneScape.GetConfig().ServerName = name;
RuneScape.GetConfig().ExperienceRate = double.Parse(expRate);
RuneScape.GetConfig().DefaultLocation = new Location(int.Parse(coords[0]), int.Parse(coords[1]), int.Parse(coords[2]));
---------- Post added at 08:43 PM ---------- Previous post was at 08:11 PM ----------
PS. sorry for the slow progress, i really dislike having to work on such over the summer.
Re: [C# - Development] Jolt Environment
Haha, I understand :).
But AJ, I really have to admit, your really going at this. So far, the interface is amazing, the feel of the program feels, original and not overbearing. The source is so nice, I don't think I have seen a new C# Programmer make something this great. Nicely organized. Maybe someday people will respect me the same way they respect you, but I got awhile to go. If you ever need a little advice or help, you can always ask me.
Good luck AJ!
Re: [C# - Development] Jolt Environment
Thanks mate, always appriated these types of comments, makes me feel better what i'm working on, enforcing me to work more efficient etc :P
PS. here's a better explanation of the XML example i gave in my last post:
Code:
/* ######################################## *\
* ### Copyright (C) 2009 AJ Ravindiran ### *
* ### HTTP://THEAJ.NET/ <AJ@THEAJ.NET> ### *
\* ######################################## */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AJRavindiran.Jolt.RuneScape.Configuration;
using AJRavindiran.Jolt.RuneScape.Models.Characters.Information;
namespace AJRavindiran.Jolt.RuneScape.Utilities.Loaders
{
/// <summary>
/// Represents a game configuration loader which is used to load the "game" configurations.
/// </summary>
public class GameConfiguratinLoader
{
#region Properties
private string mLocationX, mLocationY, mLocationZ, mServerName, mExerpienceRate;
#endregion
#region Constructor
/// <summary>
/// Constructs a new GameConfigurationLoader class.
/// Gives values to the temporary fields.
/// </summary>
public GameConfiguratinLoader()
{
// Assign temporary fields.
JoltEnvironment.GetXML("config")
.AssignValue("location-x", ref mLocationX)
.AssignValue("location-y", ref mLocationY)
.AssignValue("location-z", ref mLocationZ)
.AssignValue("server-name", ref mServerName)
.AssignValue("experience-rate", ref mExerpienceRate);
// Assign official fields.
this.parseConfigs();
}
#endregion
#region Methods
/// <summary>
/// Parses the configurations, and assigns values.
/// </summary>
private void parseConfigs()
{
RuneScape.GetGameConfig().DefaultLocation = new Location(
int.Parse(mLocationX),
int.Parse(mLocationY),
int.Parse(mLocationZ));
RuneScape.GetGameConfig().ServerName = mServerName;
RuneScape.GetGameConfig().ExperienceRate = double.Parse(mExerpienceRate);
}
#endregion
}
}
Re: [C# - Development] Jolt Environment
Awesome stuff AJ.
Its good to see your working on the internal stuff and tidying that up before working on the games features.
Good Luck with this! id love to follow it.