Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


MatsK

Member Since 21 Feb 2008
Offline Last Active Mar 22 2015 07:13 AM

Topics I've Started

GonzoNet - high level library for large scale robust networking

07 December 2014 - 06:45 AM

Thought I'd stick my library here like muchaho. GonzoNet is a library designed for large scale distributed networking (think MMO.)
It currently only supports TCP, UDP might be added in the future (UDP is uncommon for MMOs and so wasn't considered important when designing)
Unlike a lot of other libraries out there, GonzoNet does not impose a protocol on an application, and so is more like a high level wrapper on top of .NETs asynchronous sockets.
The code hasn't been cross compiled, but it uses no special namespaces that you shouldn't be able to find in Mono.
It has been tested with up to 300 concurrent users in a real setting (Though no actual "gameplay" was involved, as the project it is used for hasn't progressed further than the character creation/selection/login stage.)
GonzoNet supports authentication and encryption using Diffie Hellman EC, which was actually suggested to me on these boards!


Login confusion

06 December 2014 - 02:10 PM

Given the following:

        /// <summary>
        /// Received client token.
        /// </summary>
        public static void HandleCityToken(NetworkClient Client, ProcessedPacket P)
        {
            try
            {
                bool ClientAuthenticated = false;
 
                using (DataAccess db = DataAccess.Get())
                {
                    string Token = P.ReadString();
 
                    foreach (ClientToken Tok in NetworkFacade.TransferringClients)
                    {
                        //Token matched, so client must have logged in through login server first.
                        if (Tok.Token.Equals(Token, StringComparison.InvariantCultureIgnoreCase))
                        {
                            ClientAuthenticated = true;
 
                            Character Char = db.Characters.GetForCharacterGUID(new Guid(Tok.CharacterGUID));
                            if (Char != null)
                            {
                                lock(NetworkFacade.CurrentSession)
                                    NetworkFacade.CurrentSession.AddPlayer(Client, Char);
 
                                PacketStream SuccessPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0);
                                SuccessPacket.WriteByte((byte)CityTransferStatus.Success);
                                Client.SendEncrypted((byte)PacketType.CITY_TOKEN, SuccessPacket.ToArray());
 
                                break;
                            }
                            else
                            {
                                ClientAuthenticated = false;
                                break;
                            }
                        }
                    }
 
                    if (!ClientAuthenticated)
                    {
                        PacketStream ErrorPacket = new PacketStream((byte)PacketType.CITY_TOKEN, 0);
                        ErrorPacket.WriteByte((byte)CityTransferStatus.GeneralError);
                        Client.SendEncrypted((byte)PacketType.CITY_TOKEN, ErrorPacket.ToArray());
                    }
                }
            }
            catch (Exception E)
            {
                Logger.LogDebug("Exception in HandleCityToken: " + E.ToString());
            }
        }
 
 
(...)
 
        private Dictionary<NetworkClient, Character> m_PlayingCharacters = new Dictionary<NetworkClient, Character>();
 
        /// <summary>
        /// Adds a player to the current session.
        /// </summary>
        /// <param name="Client">The player's client.</param>
        /// <param name="Char">The player's character.</param>
        public void AddPlayer(NetworkClient Client, Character Char)
        {
            lock (m_PlayingCharacters)
            {
                foreach (KeyValuePair<NetworkClient, Character> KVP in m_PlayingCharacters)
                {
                    ClientPacketSenders.SendPlayerJoinSession(KVP.Key, Char);
                    //Send a bunch of these in reverse (to the player joining the session).
                    ClientPacketSenders.SendPlayerJoinSession(Client, KVP.Value);
                }
 
                m_PlayingCharacters.Add(Client, Char);
            }
        }

why do BOTH players receive information about the other (or self?) when I log on using the same account, but NONE receive any information when I log in using two different accounts o_O

The answer should be blindingly obvious, I can't see it.


Cryptography - am I doing it right?

27 March 2014 - 10:24 AM

I'm trying to establish a secure connection in C#, and I'm not sure I'm doing it right. :(

 

Here is my encryption class:

/*The contents of this file are subject to the Mozilla Public License Version 1.1
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is the GonzoNet.

The Initial Developer of the Original Code is
Mats 'Afr0' Vederhus. All Rights Reserved.

Contributor(s): ______________________________________.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace GonzoNet.Encryption
{
    public class ARC4Encryptor : Encryptor
    {
        private DESCryptoServiceProvider m_CryptoService = new DESCryptoServiceProvider();
        private ICryptoTransform m_DecryptTransformer, m_EncryptTransformer;
        public byte[] EncryptionKey;

        public ARC4Encryptor(string Password)
            : base(Password)
        {
            PasswordDeriveBytes Pwd = new PasswordDeriveBytes(Encoding.ASCII.GetBytes(Password), 
                Encoding.ASCII.GetBytes("SALT"), "SHA1", 10);
            EncryptionKey = Pwd.GetBytes(8);
            m_DecryptTransformer = m_CryptoService.CreateDecryptor(EncryptionKey, Encoding.ASCII.GetBytes("@1B2c3D4e5F6g7H8"));
            m_EncryptTransformer = m_CryptoService.CreateEncryptor(EncryptionKey, Encoding.ASCII.GetBytes("@1B2c3D4e5F6g7H8"));
        }

        public ARC4Encryptor(string Password, byte[] EncKey)
            : base(Password)
        {
            PasswordDeriveBytes Pwd = new PasswordDeriveBytes(Encoding.ASCII.GetBytes(Password),
                Encoding.ASCII.GetBytes("SALT"), "SHA1", 10);
            EncryptionKey = EncKey;
            m_DecryptTransformer = m_CryptoService.CreateDecryptor(EncryptionKey, Encoding.ASCII.GetBytes("@1B2c3D4e5F6g7H8"));
            m_EncryptTransformer = m_CryptoService.CreateEncryptor(EncryptionKey, Encoding.ASCII.GetBytes("@1B2c3D4e5F6g7H8"));
        }

        public override DecryptionArgsContainer GetDecryptionArgsContainer()
        {
            DecryptionArgsContainer DArgsContainer = new DecryptionArgsContainer();
            DArgsContainer.ARC4DecryptArgs = new ARC4DecryptionArgs();
            DArgsContainer.ARC4DecryptArgs.Transformer = m_DecryptTransformer;

            return DArgsContainer;
        }

        public override byte[] FinalizePacket(byte PacketID, byte[] PacketData)
        {
            MemoryStream FinalizedPacket = new MemoryStream();
            BinaryWriter PacketWriter = new BinaryWriter(FinalizedPacket);

            MemoryStream TempStream = new MemoryStream();
            CryptoStream EncryptedStream = new CryptoStream(TempStream,
                m_EncryptTransformer, CryptoStreamMode.Write);
            EncryptedStream.Write(PacketData, 0, PacketData.Length);
            EncryptedStream.FlushFinalBlock();

            PacketWriter.Write(PacketID);
            //The length of the encrypted data can be longer or smaller than the original length,
            //so write the length of the encrypted data.
            PacketWriter.Write((ushort)((long)PacketHeaders.ENCRYPTED + TempStream.Length));
            //Also write the length of the unencrypted data.
            PacketWriter.Write((ushort)PacketData.Length);
            PacketWriter.Flush();

            PacketWriter.Write(TempStream.ToArray());
            PacketWriter.Flush();

            byte[] ReturnPacket = FinalizedPacket.ToArray();

            PacketWriter.Close();

            return ReturnPacket;
        }

        public override MemoryStream DecryptPacket(PacketStream EncryptedPacket, DecryptionArgsContainer DecryptionArgs)
        {
            CryptoStream CStream = new CryptoStream(EncryptedPacket, m_DecryptTransformer, CryptoStreamMode.Read);

            byte[] DecryptedBuffer = new byte[DecryptionArgs.UnencryptedLength];
            CStream.Read(DecryptedBuffer, 0, DecryptedBuffer.Length);

            return new MemoryStream(DecryptedBuffer);
        }
    }
}

Then I initialize it as such on the client and server side:

            //Doing the encryption this way eliminates the need to send key across the wire! :D
            SaltedHash Hash = new SaltedHash(new SHA512Managed(), Args.Username.Length);
            byte[] HashBuf = Hash.ComputePasswordHash(Args.Username, Args.Password);
            Args.Enc = new GonzoNet.Encryption.ARC4Encryptor(Convert.ToBase64String(HashBuf));

Then when establishing the secure connection, I'm sending the hash across. What I'm wondering is: Could the hash be used to generate the key by a man-in-the-middle attacker?

If so, would it help to Blowfish the hash using itself as they key, so that if the hash stored in the DB is correct, it will be able to decrypt itself?

Should I just rewrite the protocol using Diffie-Helllman?


Rotating with versors...

17 October 2012 - 11:01 AM

Can someone please explain how to rotate using a versor in XNA?
I'm trying to setup a skeletal render using the SKEL format in XNA;

"Rotation - A normalized quaternion, called a "versor", consisting of X,Y,Z,W coordinates, each a 32-bit little-endian float, which specify the default direction of rotation"

It seems the common way to rotate in XNA is to create matrix from a Vector3 instance. I've tried creating a matrix using Matrix.CreateFromQuaternion(), but that doesn't seem to work very well. Here's the code I'm currently using;

	    /// <summary>
	    /// Compute the absolute transformation for this bone.
	    /// </summary>
	    public void ComputeAbsoluteTransform()
	    {
		    if (ParentName != "NULL")
		    {
				    m_AbsoluteTransform = Matrix.CreateFromQuaternion(GlobalRotation) * Matrix.CreateTranslation(GlobalTranslation) * Parent.AbsoluteTransform;
		    }
		    //This bone didn't have a parent, which means it is probably the root bone.
		    else
		    {
			    m_AbsoluteTransform =  Matrix.CreateFromQuaternion(GlobalRotation) * Matrix.CreateTranslation(GlobalTranslation);
		    }
	    }

I've searched for examples, and the most relevant I've been able to find so far is this one. It doesn't help me very much though...

Please help, how do I do this??

Screen to world coordinates

05 August 2012 - 11:22 AM

Hi!
I'm rendering 3D on top of 2D, and it seems to be working, but I need to be able to render a specific mesh at, say - 10, 10 in screen coordinates.
How?

My current approach involves using Viewport.Unproject(), but it doesn't seem to be working;

[source lang="csharp"] Vector3 NearScreenPoint = new Vector3(0, 0, 0); Vector3 FarScreenPoint = new Vector3(0, 0, 1); Vector3 NearWorldPoint = m_Scene.SceneMgr.Device.Viewport.Unproject(NearScreenPoint, m_Scene.SceneMgr.ProjectionMatrix, m_Scene.SceneMgr.ViewMatrix, m_Scene.SceneMgr.WorldMatrix); Vector3 FarWorldPoint = m_Scene.SceneMgr.Device.Viewport.Unproject(FarScreenPoint, m_Scene.SceneMgr.ProjectionMatrix, m_Scene.SceneMgr.ViewMatrix, m_Scene.SceneMgr.WorldMatrix); Vector3 Direction = FarWorldPoint - NearWorldPoint; Direction.Normalize(); if (m_CurrentHeadMeshes.Count > 0) { for (int i = 0; i < m_CurrentHeadMeshes[0].VertexTexNormalPositions.Length; i++) { /*Vector4 Position = new Vector4(m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position, 1); Matrix WorldMat = Matrix.CreateWorld(new Vector3(0, 0, 0), Vector3.Forward, new Vector3(0, 1, 0)); Vector4.Transform(ref Position, ref WorldMat, out Position); Position /= Position.W; m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position.X = Position.X; m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position.Y = Position.Y; m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position.Z = Position.Z;*/ m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position *= Direction; } }[/source]

I also want to rotate the mesh around it's X-axis, but I commented out the code for doing that since it complicated things. Anyway, here is my entire code:

[source lang="csharp"]using System;using System.Collections.Generic;using System.Text;using System.IO;using SimsLib.ThreeD;using Microsoft.Xna.Framework;using Microsoft.Xna.Framework.Graphics;using LogThis;namespace TSOClient.ThreeD{ /// <summary> /// Represents a surface for rendering 3D elements (sims) on top of UI elements. /// </summary> public class UI3DView : ThreeDElement { private List<BasicEffect> m_Effects; private float m_Rotation; private List<Mesh> m_CurrentHeadMeshes; private List<Texture2D> m_HeadTextures; private int m_Width, m_Height; private bool m_SingleRenderer = true; private SpriteBatch m_SBatch; private Camera2D Cam = new Camera2D(); /// <summary> /// Constructs a new UI3DView instance. /// </summary> /// <param name="Width">The width of this UI3DView surface.</param> /// <param name="Height">The height of this UI3DView surface.</param> /// <param name="SingleRenderer">Will this surface be used to render a single, or multiple sims?</param> /// <param name="Screen">The ThreeDScene instance with which to create this UI3DView instance.</param> /// <param name="StrID">The string ID for this UI3DView instance.</param> public UI3DView(int Width, int Height, bool SingleRenderer, ThreeDScene Screen, string StrID) : base(Screen) { m_Effects = new List<BasicEffect>(); m_Width = Width; m_Height = Height; m_SingleRenderer = SingleRenderer; m_CurrentHeadMeshes = new List<Mesh>(); m_HeadTextures = new List<Texture2D>(); m_SBatch = new SpriteBatch(m_Scene.SceneMgr.Device); m_Scene.SceneMgr.Device.DeviceReset += new EventHandler(GraphicsDevice_DeviceReset); } /// <summary> /// Occurs when the graphicsdevice was reset, meaning all 3D resources /// have to be recreated. /// </summary> private void GraphicsDevice_DeviceReset(object sender, EventArgs e) { for (int i = 0; i < m_Effects.Count; i++) m_Effects[i] = new BasicEffect(m_Scene.SceneMgr.Device, null); m_Scene.SceneMgr.Device.VertexDeclaration = new VertexDeclaration(m_Scene.SceneMgr.Device, VertexPositionNormalTexture.VertexElements); m_Scene.SceneMgr.Device.RenderState.CullMode = CullMode.None; // Create camera and projection matrix m_Scene.SceneMgr.WorldMatrix = Matrix.Identity; m_Scene.SceneMgr.ViewMatrix = Matrix.CreateLookAt(Vector3.Right * 5, Vector3.Zero, Vector3.Down); m_Scene.SceneMgr.ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.Pi / 4.0f, (float)m_Scene.SceneMgr.Device.PresentationParameters.BackBufferWidth / (float)m_Scene.SceneMgr.Device.PresentationParameters.BackBufferHeight, 1.0f, 100.0f); } /// <summary> /// Loads a head mesh. /// </summary> /// <param name="MeshID">The ID of the mesh to load.</param> /// <param name="TexID">The ID of the texture to load.</param> public void LoadHeadMesh(Outfit Outf, int SkinColor) { Appearance Apr; switch (SkinColor) { case 0: Apr = new Appearance(ContentManager.GetResourceFromLongID(Outf.LightAppearanceID)); break; case 1: Apr = new Appearance(ContentManager.GetResourceFromLongID(Outf.MediumAppearanceID)); break; case 2: Apr = new Appearance(ContentManager.GetResourceFromLongID(Outf.DarkAppearanceID)); break; default: Apr = new Appearance(ContentManager.GetResourceFromLongID(Outf.LightAppearanceID)); break; } Binding Bnd = new Binding(ContentManager.GetResourceFromLongID(Apr.BindingIDs[0])); if (m_CurrentHeadMeshes.Count > 0) { if (!m_SingleRenderer) { m_Effects.Add(new BasicEffect(m_Scene.SceneMgr.Device, null)); m_CurrentHeadMeshes.Add(new Mesh(ContentManager.GetResourceFromLongID(Bnd.MeshAssetID), false)); m_CurrentHeadMeshes[m_CurrentHeadMeshes.Count - 1].ProcessMesh(); m_HeadTextures.Add(Texture2D.FromFile(m_Scene.SceneMgr.Device, new MemoryStream(ContentManager.GetResourceFromLongID(Bnd.TextureAssetID)))); } else { m_Effects[0] = new BasicEffect(m_Scene.SceneMgr.Device, null); m_CurrentHeadMeshes[0] = new Mesh(ContentManager.GetResourceFromLongID(Bnd.MeshAssetID), false); m_CurrentHeadMeshes[m_CurrentHeadMeshes.Count - 1].ProcessMesh(); m_HeadTextures[0] = Texture2D.FromFile(m_Scene.SceneMgr.Device, new MemoryStream(ContentManager.GetResourceFromLongID(Bnd.TextureAssetID))); Vector3 NearScreenPoint = new Vector3(0, 0, 0); Vector3 FarScreenPoint = new Vector3(0, 0, 1); Vector3 NearWorldPoint = m_Scene.SceneMgr.Device.Viewport.Unproject(NearScreenPoint, m_Scene.SceneMgr.ProjectionMatrix, m_Scene.SceneMgr.ViewMatrix, m_Scene.SceneMgr.WorldMatrix); Vector3 FarWorldPoint = m_Scene.SceneMgr.Device.Viewport.Unproject(FarScreenPoint, m_Scene.SceneMgr.ProjectionMatrix, m_Scene.SceneMgr.ViewMatrix, m_Scene.SceneMgr.WorldMatrix); Vector3 Direction = FarWorldPoint - NearWorldPoint; Direction.Normalize(); if (m_CurrentHeadMeshes.Count > 0) { for (int i = 0; i < m_CurrentHeadMeshes[0].VertexTexNormalPositions.Length; i++) { /*Vector4 Position = new Vector4(m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position, 1); Matrix WorldMat = Matrix.CreateWorld(new Vector3(0, 0, 0), Vector3.Forward, new Vector3(0, 1, 0)); Vector4.Transform(ref Position, ref WorldMat, out Position); Position /= Position.W; m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position.X = Position.X; m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position.Y = Position.Y; m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position.Z = Position.Z;*/ m_CurrentHeadMeshes[0].VertexTexNormalPositions[i].Position *= Direction; } } } } else { m_Effects.Add(new BasicEffect(m_Scene.SceneMgr.Device, null)); m_CurrentHeadMeshes.Add(new Mesh(ContentManager.GetResourceFromLongID(Bnd.MeshAssetID), false)); m_CurrentHeadMeshes[m_CurrentHeadMeshes.Count - 1].ProcessMesh(); m_HeadTextures.Add(Texture2D.FromFile(m_Scene.SceneMgr.Device, new MemoryStream(ContentManager.GetResourceFromLongID(Bnd.TextureAssetID)))); } } public override void Update(GameTime GTime) { /*m_Rotation += 0.01f; m_Scene.SceneMgr.WorldMatrix = Matrix.CreateRotationX(m_Rotation);*/ base.Update(GTime); } public override void Draw() { base.Draw(); for (int i = 0; i < m_Effects.Count; i++) { for (int j = 0; j < m_HeadTextures.Count; j++) { if (m_HeadTextures[j] != null) { m_Effects[i].World = m_Scene.SceneMgr.WorldMatrix; m_Effects[i].View = m_Scene.SceneMgr.ViewMatrix; m_Effects[i].Projection = m_Scene.SceneMgr.ProjectionMatrix; m_Effects[i].Texture = m_HeadTextures[j]; m_Effects[i].TextureEnabled = true; m_Effects[i].EnableDefaultLighting(); m_Effects[i].CommitChanges(); // Draw m_Effects[i].Begin(); for (int k = 0; k < m_Effects[i].Techniques.Count; k++) { foreach (EffectPass Pass in m_Effects[i].Techniques[k].Passes) { Pass.Begin(); foreach (Mesh Msh in m_CurrentHeadMeshes) { foreach (Face Fce in Msh.Faces) { if (Msh.VertexTexNormalPositions != null) { VertexPositionNormalTexture[] Vertex = new VertexPositionNormalTexture[3]; Vertex[0] = Msh.VertexTexNormalPositions[Fce.AVertexIndex]; Vertex[1] = Msh.VertexTexNormalPositions[Fce.BVertexIndex]; Vertex[2] = Msh.VertexTexNormalPositions[Fce.CVertexIndex]; Vertex[0].TextureCoordinate = Msh.VertexTexNormalPositions[Fce.AVertexIndex].TextureCoordinate; Vertex[1].TextureCoordinate = Msh.VertexTexNormalPositions[Fce.BVertexIndex].TextureCoordinate; Vertex[2].TextureCoordinate = Msh.VertexTexNormalPositions[Fce.CVertexIndex].TextureCoordinate; m_Scene.SceneMgr.Device.DrawUserPrimitives<VertexPositionNormalTexture>( PrimitiveType.TriangleList, Vertex, 0, 1); } } } Pass.End(); m_Effects[i].End(); } } } } } }}[/source]
Also, here's my View, World and Projection:

[source lang="csharp"] m_WorldMatrix = Matrix.Identity; m_ViewMatrix = Matrix.CreateLookAt(Vector3.Backward * 5, Vector3.Zero, Vector3.Right); m_ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.Pi / 4.0f, (float)Device.PresentationParameters.BackBufferWidth / (float)Device.PresentationParameters.BackBufferHeight, 1.0f, 100.0f);[/source]

I've been Googling around for answers to this issue for some time now, but everything seems to revolve around picking, which isn't helping me.

PARTNERS