• Sábado 20 de Abril de 2024, 14:50

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Temas - U2_Caparzo

Páginas: [1]
1
C# / Algoritmos que hayan programado
« en: Lunes 1 de Julio de 2013, 10:27 »
Hola a todos, lo que les queria pedir era su experiencia en cuanto a algoritmos "famosos" que hayan hecho, con una breve explicacion, cita o link sobre como funciona el algoritmo para intentar hacerlos, por ejemplo el metodo simplex que fue posteado; por alguna razon me interese bastante en esto, estoy estudiando un poco el algoritmo A* ultimamente(aunque es algo dificil de hacer global), y la verdad me interesa bastante el tema, espero no sea el unico tratando de re-hacer la misma rueda  :nosweat: gracias de antemano.
PD: Por si a alguien le interesa el algoritmo A* yo comence a entenderlo gracias a este articulo http://www.policyalmanac.org/games/aStarTutorial.htm y obviamente de otros sitios que voy viendo, pero principalmente ese.

2
C# / Base de datos en base a FileStreams
« en: Jueves 14 de Febrero de 2013, 04:57 »
Hola a todos.
Hoy vengo con algo un poco mas avanzado(no avanzado en nivel de programacion, sino que en cantidad ^^) a lo que antes habia puesto aqui.
Pasa que por alguna razon, MySql es excesivamente lento en mi pc(sobre 1 segundo para ejecutar un comando) y decidi hacer una base de datos con FileStreams, no soy muy experimentado como programador, por eso decidi postearlo aqui, porque quisiera comentarios de que esta mal, o el porque no es una buena idea(en caso de no serlo), que seria una buena idea para mejorarlo, etc...

Funciona de la siguiente manera.
-Se crea un archivo .map que contiene las ubicaciones de cada valor dentro del archivo, este se crea antes de usar la base de datos(como en Sql)
-Al crear la clase DBEngine, se escoge una Tabla(una carpeta donde estan los archivos y asi se obtienen los datos cargados previamente del .map)
-Se usa el metodo Select() para escoger un objeto (archivo sobre el cual actuara el FileStream), en este metodo se crea el FileStream.

2 metodos principales para escribir y leer, los demas son solo conversiones a otros tipos de variables.

DBEngine hereda la interface IDisposable para usar la palabra clave 'using' como con cualquier otro tipo de Stream

MappedFile.cs
Código: [Seleccionar]
    //Field vs offset vs Size
    using Map = Selector<string, int, int>;

    /// <summary>
    /// clase con los mapas de los archivos de la database
    /// </summary>
    internal class MappedFile
    {
        static bool hasLoadedMaps = false;
        const string MapsPath = "C:\\Database\\DBMaps\\";
        /// <summary>
        /// table name vs fileMap
        /// </summary>
        static Dictionary<string, Map> DBMaps = new Dictionary<string, Map>();
        static void GetMaps()
        {
            if (hasLoadedMaps)
                return;
            if (!Directory.Exists(MapsPath))
                Directory.CreateDirectory(MapsPath);
            foreach (string file in Directory.GetFiles(MapsPath))
            {
                if (file.EndsWith(".map"))
                {
                    Map map = new Map();
                    StreamReader sr = new StreamReader(file);
                    while (sr.Peek() > 0)
                    {
                        string line = sr.ReadLine();
                        if (line.Contains('='))
                        {
                            string[] field = line.Split('=');
                            map.TryAdd(field[0], int.Parse(field[1]), int.Parse(field[2]));
                        }
                    }
                    string mapName = file.Substring(MapsPath.Length);
                    mapName = mapName.Remove(mapName.Length - 4);
                    DBMaps.Add(mapName, map);
                }

            }
            hasLoadedMaps = true;
        }
        public static Selector<string, int, int> GetMap(string table)
        {
            if (!hasLoadedMaps)
                GetMaps();
            if (DBMaps.ContainsKey(table))
                return DBMaps[table];
            else
                throw new Exception("El mapa para la tabla " + table + " no ha sido creado!");
        }
    }

VariableType.cs
Código: [Seleccionar]
/// <summary>
    /// Contiene el tipo de la variable y su longitudo maxima como string mas el caracter '>'
    /// </summary>
    internal class VariableSize
    {
        public const int Int8 = 4,
        Int16 = 6,
        Int32 = 11,
        Int64 = 20,
        SmallString = 30,
        MediumString = 65,
        BigString = 100;
    }

DBEngine.cs
Código: [Seleccionar]
   public class DBEngine : IDisposable
    {
        /// <summary>
        /// Obtiene el nombre del objeto que se esta manipulando
        /// </summary>
        public string CurrentObject { get; private set; }
        /// <summary>
        /// obtiene el nombre de la tabla a la que pertenece el objeto que se esta manipulando
        /// </summary>
        public string CurrentTable { get; private set; }

        const char NullChar = '~';

        private Selector<string, int, int> FileMap;
        private FileStream fs;
        /// <summary>
        /// Crea una nueva instancia de DBEngine con la tabla seleccionada
        /// </summary>
        /// <param name="Object">tabla en la que se encuentra el objeto a manipular</param>
        public DBEngine(string Table)
        {
            FileMap = MappedFile.GetMap(Table);
            CurrentTable = Table;
        }

        /// <summary>
        /// Objeto a manipular por el DBEngine
        /// </summary>
        /// <param name="Object"></param>
        public DBEngine SelectObject(string Object)
        {
            CurrentObject = Object;
            fs = new FileStream(Constants.DatabaseFolder + CurrentTable + "\\" + CurrentObject + ".dbe", FileMode.OpenOrCreate);
            return this;
        }

        /// <summary>
        /// devuelve true si el objeto existe en la base de datos, o false si no exist
        /// </summary>
        /// <param name="Object"></param>
        /// <returns></returns>
        public bool Exist(string Object)
        {
            return File.Exists(Constants.DatabaseFolder + CurrentTable + "\\" + Object + ".dbe");
        }

        /// <summary>
        /// Escribe el campo 'field' a la variable 'value'
        /// </summary>
        /// <param name="value"></param>
        /// <param name="field"></param>
        public void Write(object value, string field)
        {
            int size;
            FileMap.TryGetValue(field, out size);
            lock (fs)
            {
                StringBuilder sb = new StringBuilder(value.ToString(), size);
                sb.Append(NullChar, size - value.ToString().Length);
                int offset;
                if (FileMap.TryGetKey2(field, out offset))
                {
                    byte[] writeBuffer = Encoding.ASCII.GetBytes(sb.ToString());
                    fs.Seek(offset, SeekOrigin.Begin);
                    fs.Write(writeBuffer, 0, size);
                    fs.Flush();
                }
                else
                    throw new Exception("El campo " + field + " no existe en la tabla " + CurrentTable);
            }
        }

        private string MainRead(string field, int length)
        {
            lock (fs)
            {
                int offset;
                FileMap.TryGetKey2(field, out offset);
                StringBuilder sb = new StringBuilder(length);
                fs.Seek(offset, SeekOrigin.Begin);
                for (int i = 0; i < length; i++)
                {
                    char e;
                    e = (char)fs.ReadByte();
                    if (e == NullChar)
                        break;
                    else
                        sb.Append(e);
                }
                return sb.ToString();
            }
        }

        public bool ReadBool(string field)
        {
            return ReadByte(field) == 1;
        }

        public byte ReadByte(string field)
        {
            return byte.Parse(MainRead(field, VariableSize.Int8));
        }

        public sbyte ReadSByte(string field)
        {
            return sbyte.Parse(MainRead(field, VariableSize.Int8));
        }

        public short ReadInt16(string field)
        {
            return short.Parse(MainRead(field, VariableSize.Int16));
        }

        public ushort ReadUInt16(string field)
        {
            return ushort.Parse(MainRead(field, VariableSize.Int16));
        }

        public int ReadInt32(string field)
        {
            return int.Parse(MainRead(field, VariableSize.Int32));
        }

        public uint ReadUInt32(string field)
        {
            return uint.Parse(MainRead(field, VariableSize.Int32));
        }

        public long ReadInt64(string field)
        {
            return long.Parse(MainRead(field, VariableSize.Int64));
        }

        public ulong ReadUInt64(string field)
        {
            return ulong.Parse(MainRead(field, VariableSize.Int64));
        }

        /// <summary>
        /// Lee un String de 30 caracteres
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public string ReadSmallString(string field)
        {
            return MainRead(field, VariableSize.SmallString);
        }

        /// <summary>
        /// Lee un string de 65 caracteres
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public string ReadMediumString(string field)
        {
            return MainRead(field, VariableSize.MediumString);
        }

        /// <summary>
        /// Lee un string de 100 caracteres
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public string BigString(string field)
        {
            return MainRead(field, VariableSize.BigString);
        }

        /// <summary>
        /// Escribe los nombres de los campos y les asigna el valor nullChar('~').
        /// </summary>
        public void Create()
        {
            int length;
            //int offset;
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            StringBuilder sb = new StringBuilder();
            foreach (string field in FileMap.Keys1)
            {
                FileMap.TryGetValue(field, out length);
                sb.Append(field + '=');
                sb.Append(NullChar, length);
                sb.Append(Environment.NewLine);
            }
            byte[] writeBuffer = Encoding.ASCII.GetBytes(sb.ToString());
            fs.Write(writeBuffer, 0, writeBuffer.Length);
            sw.Stop();
            Output.Line(sw.ElapsedMilliseconds + "-" + sw.ElapsedTicks);
        }

        public void Dispose()
        {
            try
            {
                fs.Dispose();
                fs.Close();
            }
            catch { }
        }
    }

tambien usa otra clase llamada Selector que son 3 ConcurrentDictionaries para tener valores que pueden ser obtenidos desde 2 claves distintas

Código: [Seleccionar]
    public class Selector<TKey1, TKey2, TValue>
    {
        ConcurrentDictionary<TKey1, TValue> Key1ToValue;
        ConcurrentDictionary<TKey2, TKey1> Key2ToKey1;
        ConcurrentDictionary<TKey1, TKey2> Key1ToKey2;

        public Selector()
        {
            Key1ToValue = new ConcurrentDictionary<TKey1, TValue>();
            Key2ToKey1 = new ConcurrentDictionary<TKey2, TKey1>();
            Key1ToKey2 = new ConcurrentDictionary<TKey1, TKey2>();
        }

        public bool TryGetValue(TKey1 key, out TValue value)
        {
            return Key1ToValue.TryGetValue(key, out value);
        }

        public bool TryGetValue(TKey2 key2, out TValue value)
        {
            TKey1 key1;
            if (Key2ToKey1.TryGetValue(key2, out key1))
                return Key1ToValue.TryGetValue(key1, out value);
            value = default(TValue);
            return false;
        }

        public bool TryGetKey1(TKey2 key2, out TKey1 value)
        {
            return Key2ToKey1.TryGetValue(key2, out value);
        }

        public bool TryGetKey2(TKey1 key1, out TKey2 value)
        {
            return Key1ToKey2.TryGetValue(key1, out value);
        }

        public bool TryAdd(TKey1 key1, TKey2 key2, TValue value)
        {
            return (Key1ToKey2.TryAdd(key1, key2) &&
                    Key1ToValue.TryAdd(key1, value) &&
                    Key2ToKey1.TryAdd(key2, key1));
        }

        public bool TryRemove(TKey1 key1)
        {
            TValue deletedval;
            TKey1 deleted1;
            TKey2 key2;

            if (Key1ToKey2.TryRemove(key1, out key2))
                return (Key2ToKey1.TryRemove(key2, out deleted1) &&
                       Key1ToValue.TryRemove(key1, out deletedval));
            return false;



        }

        public bool ContainsKey1(TKey1 value)
        {
            return Key1ToValue.ContainsKey(value);
        }

        public bool ContainsKey2(TKey2 value)
        {
            return Key2ToKey1.ContainsKey(value);
        }

        public bool ContainsValue(TValue value)
        {
            return Key1ToValue.Values.Contains(value);
        }

        public ICollection<TKey1> Keys1
        {
            get { return Key1ToKey2.Keys; }
        }

        public ICollection<TKey2> Keys2
        {
            get { return Key2ToKey1.Keys; }
        }

        public ICollection<TValue> Values
        {
            get { return Key1ToValue.Values; }
        }
    }



Espero comentarios :)

3
C# / Acerca de escalabilidad de FileStreams
« en: Sábado 5 de Enero de 2013, 01:42 »
hola a todos, pues mi duda radica en que si es buena idea mantener varios FileStreams abiertos(actualizando datos con intervalo sobre 1 segundo), o simplemente crear uno nuevo cada vez que necesite hacerlo? es que para un emulador de servidor de un mmorpg lo estoy usando por ahora como base de datos porque se me hizo mas facil de usar que alguna sql(0 experiencia, ademas cuando he usado codigos hechos por otros, pues no me siento bien usandolo)

pues espero la opinion.

PD: este es el codigo que estoy usando

Código: [Seleccionar]
    public class Manager : IDisposable
    {
        #region Constructors
        public Manager(string _File)
        {
            fs = new FileStream(_File, FileMode.OpenOrCreate);
            sw = new StreamWriter(fs);
            sr = new StreamReader(fs);
            sb = new StringBuilder();
        }
        #endregion

        #region Private Fields

        private FileStream fs;
        private StreamWriter sw;
        private StreamReader sr;
        private StringBuilder sb;
        const char def = '*';
        const int ByteSize = 4, ShortSize = 6, IntSize = 11, LongSize = 20, StringSize = 20;

        #endregion

        #region Methods

        public void Dispose()
        {
            sw.Dispose();
            sw.Close();
        }

        private void Write(string value, int MaxLength, int position)
        {
            lock (fs)
            {
                sb.Append(value);
                sb.Append(def, MaxLength - value.Length);
                fs.Seek(position, SeekOrigin.Begin);
                sw.Write(sb.ToString());
                sb.Clear();
            }
        }

        public void WriteString(string value, int position)
        {
            Write(value, StringSize, position);
        }

        public void WriteUlong(ulong val, int position)
        {
            Write(val.ToString(), LongSize, position);
        }

        public void WriteLong(long val, int position)
        {
            Write(val.ToString(), LongSize, position);
        }

        public void WriteUInt(uint val, int position)
        {
            Write(val.ToString(), IntSize, position);
        }

        public void WriteInt(int val, int position)
        {
            Write(val.ToString(), IntSize, position);
        }

        public void WriteUshort(ushort val, int position)
        {
            Write(val.ToString(), ShortSize, position);
        }

        public void WriteShort(short val, int position)
        {
            Write(val.ToString(), ShortSize, position);
        }

        public void WriteByte(byte val, int position)
        {
            Write(val.ToString(), ByteSize, position);
        }

        public void WriteBool(bool val, int position)
        {
            WriteByte((byte)(val == true ? 1 : 0), position);
        }
       
        public string GetString(int position, int length)
        {
            lock (fs)
            {
                fs.Seek(position, SeekOrigin.Begin);
                string val = sr.ReadToEnd();
                return val.Substring(0, val.IndexOf(def));
                //return val.TrimEnd(def);
            }
        }

        public string GetString(int position)
        {
            return GetString(position, StringSize);
        }

        public ulong GetUlong(int position)
        {
            return ulong.Parse(GetString(position, LongSize));
        }

        public long GetLong(int position)
        {
            return long.Parse(GetString(position, LongSize));
        }

        public uint GetUInt(int position)
        {
            return uint.Parse(GetString(position, IntSize).TrimEnd('*'));
        }

        public int GetInt(int position)
        {
            return int.Parse(GetString(position, IntSize));
        }

        public ushort GetUshort(int position)
        {
            return ushort.Parse(GetString(position, ShortSize));
        }

        public short GetShort(int position)
        {
            return short.Parse(GetString(position, ShortSize));
        }

        public byte GetByte(int position)
        {
            return byte.Parse(GetString(position, ByteSize));
        }

        public bool GetBool(int position)
        {
            return GetByte(position) == 1 ? true : false;
        }
       
        #endregion
    }

4
C# / "Anti-flooding"
« en: Miércoles 3 de Octubre de 2012, 04:30 »
bueno, hola a todos, pues tengo una duda, hice una clase para evitar el envio masivo de paquetes de datos a un servidor de una aplicacion que hago, ya que produciria retraso en la respuesta para los otros clientes, pasa que quiero saber si la clase que hice serviria en cierto modo para detener eso, tengo fe en que si, no lo he probado si funciona como deberia, pero me parece que si,  pasa que si lo probara en mi pc, el resultado seria optimo(creo yo), quiero saber si en realidad serviria frente a varios clientes verdaderos.


Código: [Seleccionar]
public class Entry
    {
        public DateTime lastTry;
        public IClient client;
        public Entry(IClient arg)
        {
            lastTry = DateTime.Now;
            client = arg;
        }
        public void Disconnect()
        {
            client.Disconnect();
        }
    }

    /// <summary>
    /// Clase usada para evitar el envio masivo de bytes desde los clientes que no
    /// sean el que se esta manipulando.
    ///
    /// </summary>
    public class Anti_Flooding
    {
        //Indica si el Anti-Flooding esta funcionando
        static bool IsWorking;

        //Medido en segundos, es la cantidad minima de segundos que debe esperar cada
        //cliente para enviar otro packet
        const int minConnectionSleep = 3;

        //Medido en minutos, es la cantidad de minutos que no se aceptaran conexiones
        //desde el cliente que este ban
        const int BannedTime = 5;
        static Thread BannedsRemover;
        /// <summary>
        /// IP vs Client
        /// </summary>
        static SafeDictionary<string, Entry> Entries = new SafeDictionary<string, Entry>();
        static SafeDictionary<string, Entry> Banneds = new SafeDictionary<string, Entry>();
       
        /// <summary>
        /// revisa si el IClient esta ban, en caso de estarlo lo desconecta y devuelve true
        /// </summary>
        /// <param name="arg">ICliente al que se le revisara Ban</param>
        /// <returns></returns>
        public static bool isBanned(IClient arg)
        {
            if (Banneds.ContainsKey(arg.IP))
            {
                arg.Disconnect();
                return true;
            }
            return false;
        }
        public static void Try(IClient arg)
        {
            if (!IsWorking)
                return;
            if (!Entries.ContainsKey(arg.IP))
            {
                Entry entry = new Entry(arg);
                Entries.Add(arg.IP, entry);
            }
            else
            {
                Entry entry = Entries[arg.IP];
                if (entry.lastTry.AddSeconds(minConnectionSleep) > DateTime.Now)
                {
                    entry.Disconnect();
                    Entries.Remove(arg.IP);
                    Banneds.Add(arg.IP, entry);
                }

            }
        }
        public static void StartAntiFlooding()
        {
            BannedsRemover = new Thread(new ThreadStart(RemoveBanneds));
            BannedsRemover.Start();
            IsWorking = true;
        }
        public static void StopAntiFlooding()
        {
            BannedsRemover.Abort();
            IsWorking = false;
            if (Banneds.Count > 0)
            {
                foreach (Entry entry in Banneds.Values)
                {
                    Entries.Add(entry.client.IP, entry);
                    Banneds.Remove(entry.client.IP);
                }
            }
        }
        static void RemoveBanneds()
        {
            while (true)
            {
                foreach (Entry entry in Banneds.Values)
                {
                    if (entry.lastTry.AddMinutes(BannedTime) <= DateTime.Now)
                    {
                        string IP = entry.client.IP;
                        Banneds.Remove(IP);
                        Entries.Add(IP, entry);
                    }
                }
                Thread.Sleep(20000);
            }
        }
    }

en caso de que si sirva y alguien lo quiera usar de verdad, deberan implementar en la clase que tienen como cliente la interfaz IClient

Código: [Seleccionar]
public interface IClient
    {
        void Disconnect();
        string IP { get; }
    }

la clase SafeDictionary es solo un simplificador de ConcurrentDictionary para que funcione como Dictionary y poder cambiarlo rapidamente en sources que descargaba con mas de un hilo/thread

Código: [Seleccionar]
public class SafeDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>
    {
        public bool Add(TKey Key, TValue value)
        {
            return base.TryAdd(Key, value);
        }
        public new TValue this[TKey key]
        {
            get
            {
                TValue value = default(TValue);
                base.TryGetValue(key, out value);
                return value;
            }
            set
            {
                base.TryUpdate(key, value, this[key]);
            }

        }
        public bool Remove(TKey key)
        {
            TValue value;
            return base.TryRemove(key, out value);
        }


de antemano gracias

5
C# / Obtener bits y convertirlos a algun valor
« en: Viernes 21 de Septiembre de 2012, 07:42 »
Pues la verdad dudo que esto sirva de mucho en algun momento, lo queria integrar a la criptografia de una aplicacion que hacemos con un amigo, pero resulto que no era lo suficientemente rapido como para usarlo(no es que sea lento, pero si lo era para nosotros porque necesitamos transferencia de datos rapida por Tcp, y el aumentar el tiempo en varios ms no era lo ideal), asi que agrugue los metodos para todos los tipos de variables y aqui esta xD
     |10011011|
basicamente lo que hice es lo siguiente
suponiendo que lo que esta dentro de las lineas '|' es un byte (con un tamaño de 8 bits),  para obtener cada bit lo que hago es.
aplico el operador ">" o "<" para correr los bits, uso ">>" con una cantidad igual a 7, si el numero es 0, continuo corriendo los bits hasta que sea distinto de 0, asi obtengo la cantidad de bits en uso por el numero para crear la matriz de bytes(conteniendo cada byte uno 1 o un 0).

luego empujo los bits hacia la izquierda con "<<" para eliminar los bits anteriores al que deseo obtener. y luego a la izquierda, para que me quede como valores posibles un 1 o un 0 (Esto es solo util despues de haber obtenido el primer bit)

luego empujo uso >> 7 para obtener el byte, y lo agrego a la matriz para finalmente tener el bit dentro de la matriz

asi por ejemplo tenemos el siguiente byte, y queremos obtener el bit en negrita
 
  |00110011|
  aplico << 6  y queda
   |11000000|
aplico >> 7 y queda
  |00000001|
y como un numero con esos bits es igual a 1, o si el bit fuera 0 seria 0, obtengo el bit, y asi lo agrego a la matriz

al finalizar me di cuenta de que los bits estaban entregados al reves, asi que use Array.Reverse para invertirlos.

tambien agrugue los metodos para revertir el proceso.

la clase:

Código: [Seleccionar]

/// <summary>
    /// Clase con metodos para obtener una matriz de bits de un valor numerico
    /// o el valor numerico de una matriz de bits
    /// </summary>
    public class Bits
    {
        public static byte[] GetBits(sbyte source)
        {
            return GetBits((byte)source);
        }

        public static byte[] GetBits(byte source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 8;
            byte Copy = source;
            for (int i = 7; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (7 - i);
                Copy >>= 7;
                CompleteBits[i] = Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static byte[] GetBits(short source)
        {
            return GetBits((ushort)source);
        }

        public static byte[] GetBits(ushort source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 16;
            ushort Copy = source;
            for (int i = 15; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (15 - i);
                Copy >>= 15;
                CompleteBits[i] = (byte)Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static byte[] GetBits(int source)
        {
            return GetBits((uint)source);
        }

        public static byte[] GetBits(uint source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 32;
            uint Copy = source;
            for (int i = 31; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (31 - i);
                Copy >>= 31;
                CompleteBits[i] = (byte)Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static byte[] GetBits(long source)
        {
            return GetBits((ulong)source);
        }

        public static byte[] GetBits(ulong source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 64;
            ulong Copy = source;
            for (int i = 63; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (63 - i);
                Copy >>= 63;
                CompleteBits[i] = (byte)Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static sbyte GetSByte(byte[] source)
        {
            return (sbyte)GetByte(source);
        }

        public static byte GetByte(byte[] source)
        {
            byte ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (byte)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }

        public static short GetInt16(byte[] source)
        {
            return (short)GetUInt32(source);
        }

        public static ushort GetUInt16(byte[] source)
        {
            ushort ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (ushort)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }

        public static int GetInt32(byte[] source)
        {
            return (int)GetUInt32(source);
        }

        public static uint GetUInt32(byte[] source)
        {
            uint ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (uint)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }

        public static long GetInt64(byte[] source)
        {
            return (long)GetUInt64(source);
        }

        public static ulong GetUInt64(byte[] source)
        {
            ulong ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (ulong)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }
    }

si no entienden que es, vayan a la calculadora de windows, la dejan en modo cientifico, escriben cualquier numero en "dec" y luego apretan en "bin", lo que obtienes, lo tendras como byte[] usando los metodos que puse.

No se si hayan mejores maneras de hacerlo dadas por .Net pero esto funciona relativamente rapido

6
C# / Editar un WindowsForm desde un sub-proceso(thread)
« en: Domingo 2 de Septiembre de 2012, 18:06 »
Hola a todos, mientras hacia una aplicacion, en la cual agrego controles dinamicamente por asi decirlo, la aplicacion se congelaba y cerraba, asi que puse el metodo en un thread, pero al hacer eso me dio el siguiente error

Operación no válida a través de subprocesos: Se tuvo acceso al control 'Form2' desde un subproceso distinto a aquel en que lo creó.

luego de investigar un poco encontre esta solucion, quizas muchos de ustedes lo hallaran basico o inutil, pero me sirvio bastante.

Asi es como dara el error
Código: [Seleccionar]
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        delegate void crearBoton();
        private void Form2_Load(object sender, EventArgs e)
        {
            Thread T = new Thread(new ThreadStart(NuevoBoton));
            T.Start();
        }
        private void NuevoBoton()
        {
            Button B = new Button();
            this.Controls.Add(B);
        }
    }

para hacerlo agregaremos un delegate void dentro de la clase Form2, ver si el Forn2 necesita invocacion, y si lo necesita invocar la clase pasando nuestro delegate como parametro.

Código: [Seleccionar]
public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        delegate void crearBoton();
        private void Form2_Load(object sender, EventArgs e)
        {
            Thread T = new Thread(new ThreadStart(NuevoBoton));
            T.Start();
        }
        private void NuevoBoton()
        {
            if (this.InvokeRequired)
            {
                crearBoton CB = new crearBoton(NuevoBoton);//Creamos una instancia del delegate
                                      //pasandole el metodo que estamos ejecutando como parametro
                this.Invoke(CB);  //invocamos el Form pasando el delegate void que recien creamos
            }
            else
            {
                Button B = new Button();
                this.Controls.Add(B);
            }
        }
    }

espero que a alguien le sirva  :suerte:

7
C# / Herencia de clases(resuelto :P)
« en: Domingo 8 de Julio de 2012, 20:13 »
Pues quisiera hacer una pregunta bastante corta, he estado haciendo todo lo relacionado a paquetes en un proyecto que tengo, pero resulta que tengo lo siguiente

Clase Packet
{
     muchos metodos xD
}

clase XXXX : Packet// son 4 por los morbosos  :think:
{
      algunas variables
}


pasa que quiero cambiar los valores de ciertas variables en la clase XXXX, pero intellisense al presionar XXXX. tambien muestra todos los metodos de la clase Packet.

Mi pregunta es si es posible hacer que solo muestre las variables de la clase XXXX?
 no se si podra heredar metodos con accesibilidad private, o algo que se pueda hacer?

gracias de antemano



SOLUCION ENCONTRADA, USO protected EN VEZ DE public EN LOS METODOS DE LA CLASE PACKET, GRACIAS DE TODOS MODOS

8
C# / Dictionary de clases?
« en: Sábado 16 de Junio de 2012, 03:30 »
Hola a todos, hace poco comenze a escribir un emulador para un juego online(apoyado de varias guias obviamente) y ahora tengo que enviar muchos paquetes, las estructuras para estos las tengo en clases (asi no tengo que escribir el paquete desde 0, sino que cambio algunos valores y lo envio), pero la verdad no quiero crear una clase nueva cada vez que envio un paquete, asi que deseo guardar las clases usadas en un Dictionary para volver a usarlas, pero la duda esta en como las almaceno?

la idea es que sea algo como

Dictionary<ushort, ClasesDeLosPaquetes> MisPaquetes.

como puedo guardar clases en el dictionary? habia pensado en objects, o usar interfaces y hacer los paquetes derivados de la inetrface, pero luego no podria convertir el object o interface a la clase del paquete que requiero. como lo podria hacer?

de antemano gracias

9
C# / Constructor de paquetes
« en: Lunes 28 de Mayo de 2012, 07:38 »
Hola a todos, esta es una clase que quizas a alguien le sirva, es para construir paquetes que son enviados a traves de la internet, solo he testeado agregar bytes y ints, pero deberia funcionar con el resto, habran maneras mejores pero me siento feliz por haber hecho esto ^^
Lo hice ya que como proyecto de aprendizaje estoy programando un servidor de Conquer online desde "0" (los sockets y la criptografia son copiadas)

Esta en ingles porque la comunidad mas desarrollada en servidores de este juego es de E.E.U.U







Código: [Seleccionar]
    public class Builder
    {
        public static void WriteByte(byte val, int offset, byte[] Data)
        {
            Data[offset] = val;
        }
        public static void WriteUInt16(ushort val, int offset, byte[] Data)
        {
            Data[offset] = (byte)val;
            Data[++offset] = (byte)(val >> 8);
        }
        public static void WriteUInt32(uint val, int offset, byte[] Data)
        {
            Data[offset] = (byte)val;
            Data[++offset] = (byte)(val >> 8);
            Data[++offset] = (byte)(val >> 16);
            Data[++offset] = (byte)(val >> 24);
        }
        public static void WriteUInt64(ulong val, int offset, byte[] Data)
        {
            Data[offset] = (byte)val;
            Data[++offset] = (byte)(val >> 8);
            Data[++offset] = (byte)(val >> 16);
            Data[++offset] = (byte)(val >> 24);
            Data[++offset] = (byte)(val >> 32);
            Data[++offset] = (byte)(val >> 40);
            Data[++offset] = (byte)(val >> 48);
            Data[++offset] = (byte)(val >> 56);
        }
        public static void WriteString(string val, int offset, byte[] Data)
        {
            for (int i = 0; i < val.Length; i++)
            {
                Data[offset + i] = (byte)val[i];
            }
        }
    }

10
C# / Conectar 2 aplicaciones sin sockets
« en: Viernes 27 de Abril de 2012, 22:20 »
Hola a todos, para explicar un poco el porque, yo me entretengo editando un emulador de un mmorpg en C#, pero la source no es de lo mejor que digamos y es posible que se cierre, la base de datos que usa, es en archivos escritos con BinaryWriter, asi que no puedo guardar un cambio de un personaje inmediatamente despues del cambio porque tengo que guardar todo, entonces la unica solucion que existe es guardarlo cada 10 segundos(se pueden cambiar pero no es lo que quiero).

Lo que se me ocurrio es hacer una aplicacion en C#, que reciba la informacion desde el servidor del juego, asi podria enviar por ejemplo, un solo cambio a la aplicacion, y esta la almacenaria y luego la guardaria, entonces, en vez de escribir todos los datos en el archivo, envia ese cambio a la nueva aplicacion, y esta la guarda cada cierto tiempo, asi aunque cayera el servidor, podria mantener los datos a salvo.

Ojala alguien pueda ayudarme con esto, la idea es hacerlo sin sockets porque me imagino que serian mas lentos, ademas de innecesarios ya que ambos estarian en la misma PC.

Links, nombres, todo me sirve.

Gracias de antemano

11
C# / duda en editor de archivos ini
« en: Jueves 12 de Abril de 2012, 04:02 »
Hola a todos, bueno, he estado tratando de aplicar un poco lo que he leido en unos tutoriales, y decidi hacer un editor de archivos ini entre otras cosas, pero tengo un problema: La velocidad, con 200 campos(campo=valor, a esa parte me refiero) tarda entre 400 y 900 milisegundos, lo cual encuentro que es demasiado.

esto es lo que hice(disculpen el que lo haga en ingles, pero me acostumbre)


Código: [Seleccionar]
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using IniHandler;

namespace IniHandler
{
    struct Item
    {
        public string Section;
        public string Field;
    }
}

namespace IniManager
{
    class IniManager
    {
        byte COUNT = 0;
        string SECTION, FILE;
        string[] SECTIONS = new string[255];
        Dictionary<Item, string> ITEMS;
        StreamReader READER;
        bool READING = true;

        public IniManager(string _FILE)
        {
            COUNT = 0;
            FILE = _FILE;
            ITEMS = new Dictionary<Item, string>();
            FILL();
            READING = true;
        }

        void FILL()
        {
            string[] Lines = File.ReadAllLines(FILE);
            foreach (string Line in Lines)
            {
                ANALYZELINE(Lines);
            }
            //for (ushort i = 0; i < LINES.Length; i++)
            //{
            //    ANALYZELINE(LINES[i]);
            //}
        }

        void ANALYZELINE(string LINE)
        {
            if (LINE.Length > 0)
            {
                if (LINE[0] == '[')
                {
                    SECTIONS[COUNT] = LINE;
                    COUNT++;
                    SECTION = LINE;
                }
                else
                {
                    Item i = new Item();
                    i.Section = SECTION;
                    string[] SPLIT = LINE.Split('=');
                    i.Field = SPLIT[0];
                    ITEMS.Add(i, SPLIT[1]);
                }
            }
            else
                return;
        }

        public Item GetItem(string Section, string Field)
        {
            Item i = new Item();
            i.Section = Section;
            i.Field = Field;
            return i;
        }

        public string ReadString(string Section, string Field)
        {
            string Value;
            Item I = new Item();
            I.Section = '[' + Section + ']';
            I.Field = Field;
            ITEMS.TryGetValue(I, out Value);
            return Value;
        }

        public void Write(string Section, string Field, object Value)
        {
            StringBuilder BUILDER = new StringBuilder();
            Item I = GetItem(Section, Field);
            if (!ITEMS.ContainsKey(I))
            {
                ITEMS.Add(I, Value.ToString());
            }
            else
            {
                ITEMS.Remove(I);
                ITEMS.Add(I, Value.ToString());
            }
            for (byte i = 0; i <= COUNT; i++)
            {
                string section = SECTIONS[i];
                BUILDER.AppendLine(section);
                foreach(KeyValuePair<Item, string> item in ITEMS)
                {
                    if (item.Key.Section != section)
                        continue;
                    else
                    {
                        BUILDER.AppendLine(item.Key.Field + '=' + item.Value);
                    }
                }
            }
            File.WriteAllText(FILE, BUILDER.ToString());
        }
    }
}



ojala puedan ayudarme a mejorar esto, ya que obviamente debe ser una pesima forma por la cantidad de tiempo que toma, y que es exactamente lo que falla, tengo una idea pero la verdad no se si lo es, que seria el crear masivamente objetos a partir de la estructura "Item"

Gracias de antemano

12
C# / ¿Tipos de Bases de datos?
« en: Viernes 6 de Abril de 2012, 02:07 »
Hola a todos, se que muchos pensaran que soy un imbecil por lo que voy a rechazar, pero es que la verdad no me siento comodo usando, que son las bases de datos SQL (mysql, mssql o cualquiera)
por eso les queria pedir alternativas a esto, estuve pensando en INI pero algunos amigos no me lo recomendaron porque no es lo suficientemente rapido, estoy hablando de manejar mas de 50 archivos al mismo tiempo, actualizando datos.
por eso les queria pedir tipos de bases de datos que sean lo suficientemente rapido para estar actualizandose constantemente y poder guardar mas o menos 200 datos distintos de no mas de 40 chars de longitud en la menor cantidad de milisegundos posibles, pero intentando no sacrificar lo que es Uso de CPU y Ram debido a que es muy importante en lo que estoy "trabajando"

en resumen, necesito un tipo de base de datos con bajo uso de cpu y ram, lo mas rapido posible, y de preferencia basada en archivos, un poco de informacion de como se usa.

Gracias de antemano

13
C# / Ordenar strings en un archivo texto
« en: Domingo 11 de Marzo de 2012, 22:44 »
Hola a todos, primero que nada, me presento, soy rodrigo cordova, uso el nick de U2_Caparzo, actualmente soy estudiante de 17 años(estoy en mi ultimo año del liceo) y uno de mis intereses es continuar como estudiante de ingenieria informatica.
Paso bastante tiempo, editando un servidor de un juego(conquer), los cuales todos estan escritos en C#. Vine a este foro, porque en el foro que participaba en desarrollo de estos servidores, no hay nadie que tenga grandes conocimientos, de hecho yo escribi algo basico para que algunos aprendieran de C#.

Bueno ahora al grano.

El otro dia, estuve tratando de ordenar un archivo de texto llamado ItemAdd.ini
el archivo solo son numeros por ejemplo

123510 12 4214 32141 421421 4213 5436 534 12

los 2 primeros numeros son los que estoy tratando de ordenar, o sea que a partir de esos trato de ordeanr el archivo

el primer numero se repite siempre 12 veces
por ejemplo
123510 1 ......
123510 2 ......

ahora, estan todos desordenados, asi que lo que hice fue 2 maneras de ordenarlo que es por el primer numero o el segundo numero.

Les proveere el codigo que estoy usando, como estructura generalizada, porque no me encuentro en mi Laptop y no tengo C# aca.

se que obviamente la ineficiencia esta en el uso masivo de ciclos asi que esperaria algo de ayuda con eso.

bueno, lo que hice fue esto

tengo un List<string> llamado IDsque almacenara todas las ID (primer numero) y un byte llamado Maximo plus = 12; (el maximo base del segundo numero)

creo un array de strings de todas las lineas con File.ReadAllLines

luego
foreach(string linea in lineas)//lineas es el array anterior
{
string[] sp = linea.Split(' ');
if(!IDs.Contains(sp[0]))
    IDs.Add(sp[0]);
if(Maximo < byte.Parse(sp[1]))
   Maximo = byte.Parse(sp[1]);
}

entonces aqui viene lo feo, son 3 ciclos en total... por cierto cree un stringbuilder sb

foreach(string ID in IDs)//el List<string> que cree antes
{
    for(byte i = 1; i <= Maximo; i++);
       {
        foreach(string linea in lineas)//del array al leer el archivo
             {
                if(Line.StartsWith(ID + " " + i.ToString() + " ")/*agrego un espacio al final porque el 1 se repetiria en 1, 10, 11, y 12, etc...*/
                         sb.AppendLine(linea);
             }
       }
}

y luego escribo el stringbuilder al archivo con StreamWriter.

lo que pasa es que tarda mucho ademas de que usa bastante memoria, asi que algo de guia con esto se los agradeceria demasiado. he escuchado algo de OrderBy en List<> pero no entendi mucho como usarlo

gracias por adelantado

Páginas: [1]