Logo

¡Bienvenido a Stratos!

Acceder

Foros



Menu

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.

Mostrar Mensajes Menu

Mensajes - TrOnTxU

#106
General Programadores / Re: Detector de Colisiones 2D en C++
29 de Abril de 2011, 08:36:57 PM
Hola,

yo creo que una cosa es detectar la colision, y otra la respuesta a la misma.

Como dicen blau y fjfnaranjo hay comprobaciones simples para detectar si dos rectangulos en un plano se intersectan, y para calcular la interseccion resultante.
Detectar con que lado se produce la colision, es complicado si como dices los rectangulos varian, algunos se mueven, otros, no, unos son mas grandes que otros, etc, etc.

Como siempre: divide y venceras. Lo primero separa la deteccion (si quieres tambien puedes obtener la interseccion en el mismo metodo) de la respuesta. Un ejemplo de posibles metodos de deteccion (en pseudocodigo rollo UML), si quieres separar:

HayColision(rectA : Rect, rectB : Rect) : boolean
Intersectan(rectA : Rect, rectB : Rect, out rectC : Rect) : bool


Luego separa el procesado de la colision/respuesta con el escenario:

Para un mario (estilo clasico) compuesto por mapas de celdas o tile maps, una capa de tile map sirve de colision. Ademas en esa capa cada tile de colision puede tener sus propiedades, como por ejemplo "suelo", "techo", "pared", etc...

Si lo que tienes son una "coleccion" de rectangulos para definir las colisiones del mapa, te aconsejo que les añadas estas propiedades, u otras parecidas. Esto te puede ayudar a saber que tipo de respuesta debes procesar.
Esto te ayudaria a reducir el coste de proceso, ya que tienes informacion "precalculada".

Esto te debe servir para calcular la colision/respuesta con el escenario con todos los personajes (player, enemigos, ...)


En cuanto a las colisiones entre "sprites" (personaje, enemigos, items, oloquequieras) no entiendo para que quieres saber la direccion.
Si lo que quieres es saber si estas pisando a un enemigo rollo salto mario es facil (suponiendo que el eje de coordenadas este en el borde superior izquierdo):
personaje.y < enemigo.y && personaje.isJump


Espero que esas sean las respuestas a tus dudas  ^_^'

Un saludo


EDIT: depues de releer creo que he entendido un poco mejor la pregunta  Oo

Primero mola saber la velocidad del sprite. pero sin velocidad:
* Si como dices todo rect de escenario debe ser mayor que el rect del personaje:

Result res = NADA;
if (Intersectan(player.rect, collider, out intersecion) )
{
    if (interseccion.w == player.rect.w && interseccion.h == player.rect.h) return DENTRO; // Opcional

    if (interseccion.w > 0)
    {
        res |= (player.rect.left < collider.right) ? RIGHT : LEFT;
    }

    if (interseccion.h > 0)
    {
        res |= (player.rect.bottom > collider.up) ? DOWN : UP;
    }

}
return res;
#107
Cita de: Vicente en 29 de Abril de 2011, 03:18:20 PM
Hay juegos de verdad de PS3 que usan Mono ;)

:) si, además Unity3D 3 rula mono tb en ps3.

Para la Wii, Novell si que tiene una maquina Mono.
Para PS3 pone esto: http://www.mono-project.com/Mono:PlayStation3

Tendré que mirar cuando pueda la informacion en scedev, y en los foros, sobre como pirula en CellOS, y a ver que licencia tiene Novell para PS3.

De todas formas casi seguro que acabemos usando Unity3D para este proyecto, o sea que una cosa menos de la que tendré que preocuparme :D



Por cierto, al final he pasado de comerme la cabeza con la llamada al metdodo de la clase base y he reescrito un poco de código para que la implementación funcione sin necesidad de saltarse un escalon en la jerarquia.
En cuanto al inline voy a confiar ciegamente de momento en el compilador, más adelante ya decompilare IL y me aseguraré de que funcione todo como debe.

Bueno, gracias de nuevo.

ADEW!

#108
Muchas gracias a los dos   :)

Seguiré investigando  ;)

En cuanto a consolas he visto que se rula Mono en PS3 pero bajo linux :S

Ya os cuento algo cuando consiga que rule en las consolas

ADEW!!
#109
Cita de: blau en 29 de Abril de 2011, 12:06:01 PM
pues la otra opción que se me ocurre es con algo asi:

base.base.Escribe()

XD XD XD XD

Lo mismo he probado yo, y el MonoDevelop me dice que nainai, que el keyword base no se puede utilizar de esa manera.

Es curioso porque la dos contestaciones que has dado son las primeras que he probado y en el mismo orden XD XD

Gracias por la ayuda igualmente, tendremos que esperar a que Vicente nos resuleva los problemas como siempre XD

Un saludo.
#110
Cita de: blau en 29 de Abril de 2011, 11:55:12 AM

1) (cc as ClaseA).Escribe   


Hola, gracias por contestar. Igual es por el tema de la maquina Mono (y puede que en .NET funcione de manera diferente, aunque creo que no), pero un código del estilo:

class ClaseC : ClaseB {
public override void Escribe() {
Console.WriteLine("Hola soy clase C\n");
Console.WriteLine("Ahora muestro la clase base:");
// -- Comentado ==> base.Escribe();
                (this as ClaseA).Escribe();
}
}


Entraria en un bucle infinito de recursion, ya que aunque indiques el casting dinamico a clase A, la informacion del objeto sigue indicando que es un objeto de claseC con lo que se llamaria a ClaseC.Escribe, en vez de a ClaseA.Escribe.

Realmente es lo mismo que tener un array de "ClaseA"s, con objetos de claseA, claseB y claseC. Aunque la referencia sea de la clase base, al llamar a "Escribe" se utilizaria la tabla de funciones virtuales y se llamaria "en teoria" al metodo correspondiente a cada clase.


De todas muchas gracias :)
#111
Hola!

Sigo trasteando con C# y la maquina Mono (para scripting de entidades como siempre). Y me han vuelto a salir problemillas :)

1) Primero como llamar a un metodo sobreescrito de una clase base que no sea directamente la del "padre" de la clase, sino más bien el "abuelo", y me explico con un ejemplo tonto.
En C++ haria algo asi (lo escribo sobre la marcha, la implementacion en el mismo archivo que la declaracion y sin comprobar) pero la idea es esta:

class ClaseA {
  public:
    virtual void Escribe() { printf("Hola soy clase A\n"); }
}

class ClaseB : public ClaseA {
  public:
    virtual void Escribe() { printf("Hola soy clase B\n"); }
}

class ClaseC : public ClaseB {
  public:
    virtual void Escribe() {
      printf("Hola soy clase C\n");
      printf("Ahora muestro la clase base:\n");
      ClaseA::Escribe();
    }
}


El rollo es que ClaseC claseC(); claseC.Escribe(); esto deberia mostrar:
Hola soy clase C
Ahora muestro la clase base:
Hola soy clase A


Si esto lo hago en C#

public class ClaseA {
public virtual void Escribe() { Console.WriteLine("Hola soy clase A"); }
}

public class ClaseB : ClaseA {
public override void Escribe() { Console.WriteLine("Hola soy clase B"); }
}

class ClaseC : ClaseB {
public override void Escribe() {
Console.WriteLine("Hola soy clase C");
Console.WriteLine("Ahora muestro la clase base:");
base.Escribe();
}
}


Para el siguiente código de ejecucion:
ClaseA ca = new ClaseA();ca.Escribe();
ClaseC cc = new ClaseC(); cc.Escribe();


Obtengo la salida:
Hola soy clase A
Hola soy clase C
Ahora muestro la clase base:
Hola soy clase B


Con lo que mi problema es poder llamar al metodo "ClaseA.Escribe" desde "ClaseC.Escribe", sin pasar por el metodo "ClaseB.Escribe".
Supongo que será una chorrada como un piano pero mira que he "googleado" y no encontrado ningun ejemplo, lo más chungo es que me parece que alguna vez lo tengo que haber echo ya, pero ahora no caigo si se puede y como.


2) Y paso a la segunda pregunta chorra. Esto viene del tema de optimizaciones del compilador, y sobretodo el tema de metodos inline.
Para liar más la cosa ahora compilo las DLL de los scripts con el compilador de MonoDevelop, aunque no tendria que haber problemas en que lo compilara con el VS y luego copiar la DLL al directorio de ejecucion.

En C# no hay ninguna "palabra reservada" que inidique al compilador tu preferencia por hacer inline de una funcion, aunque por el contrario si que puedes darle un atributo a un metodo para indicarle que "no haga nunca un inline" de dicho metodo.
En un principio un metodo que ocupe menos de x bytes de codigo IL (creo que son 32) y no se llame recursivamente es firme candidato para este tipo de optimizacion.
Vale, hasta aqui todo OK. Mi problema actual: los arboles de comportamiento que he implementado para la IA utilizan un "yield return [Xe2BTResult]" como "retorno" de un metodo "IEnumerable<Xe2BTResult>", con lo que utlizo los iteradores para "simular" código de corrutinas.
Pero si quiero trazar el arbol (ver en tiempo de ejecucion que nodos estan activos y en que estado), debo guardar la informacion de estado de la "corrutina" con lo que hago esto: yield return Trazar([Xe2BTResult]). Donde Xe2BTResult es un enum y Trazar es un metodo "no estatico" de la clase nodo con una implementacion parecida a esto:
Xe2BTResult Trazar(Xe2BTResult  result)
{
#ifdef DEBUG
    m_blackboard.ChangeState(m_nodeID, result);
#endif
    return result;
}


En C++ si quisiera que en "Release" se obviara el registro del estado en la blackboard y el "jump" a la funcion implementaria Trazar como un macro "#define" sin pensarmelo dos veces.
Mi problema es saber si "Trazar" (al menos en Release cuando el #ifdef no se cumple) es candidato a optimizar mediante inline de forma que el código quedara de la siguiente manera:
En DEBUG: yield return Trazar([Xe2BTResult]); (o con toda la funcion Trazar "inlineada")
Y en RELEASE: yield return [Xe2BTResult];

Supongo que me puedo poner a decompilar IL y examinar el codigo resultante pero me gustaria que si alguien tiene experiencia con esto me comentara su opinion.
Tanto para compilador .NET como Mono.

Como alternativa he leido que algunos "Delegates" o funciones anonimas o algo asi, en C# se "desplegan" en tiempo de compilacion como funciones "inline" con lo que sustituyendo el metodo "Trazar" por algun tipo de funcion anonima podia conseguir el mismo resultado que con un "#define" o un "inline" de C++.
¿Alguna ayudita u opinión al respecto? (por cierto, me gustaria no pasar de 2.0, por lo que supongo que "Action" no funcionaria).


3) Y por fin la ultima pregunta.
En consolas Next-Gen (si suponemos la 360 y la PS3) se acabo el "codigo dinámico", todo codigo nativo no firmado no se puede ejecutar.
La maquina de .NET en un principio (y segun tengo entendido) genera "codigo maquina nativo" sobre a marcha (conforme se necesitan) a partir del codigo IL.
En XNA supongo que la solución es generar ese "codigo nativo" en el proceso de compilacion, en vez de "conforme se necesita". Y por supuesto eliminar el JIT de las features del lenguaje.
Si tengo que utilizar la maquina Mono en estas consolas:
¿la solucion que he propuesto seria la correcta?
¿opiniones al respecto?
¿alguna ayudita XD?


Bueno pues muchas gracias por anticipado, y perdonar por los "tostones" de post que pongo (ya vienen siendo habituales en mi).

ADEW!!
#112
Inteligencia Artificial / Re: Un poco perdido en A*
21 de Abril de 2011, 05:34:37 PM
Este hilo se pone interesante  :o

Mucha información y bien contrastada :)

En cuanto a utilizar behaviour tree para formaciones al estilo rts, creo que es una aproximacion. Pero personalmente, y aunque he utilizado y estoy utilizando algunas implementaciones de behavior trees (y alguna simplificacion rollo decision trees), para un RTS quizas utilizaria otros tipos de toma de decisiones. Pero quizas el planificador para controlar las tareas de cada agente y por grupo, y un diseño del arbol basada en GOALS funcione, no lo sé  ???

Para calcular las influencias de areas peligrosas, etc en un mapa de "celdas" hay bastantes articulos de "influence maps" por ahi.
En aigamedev hay algunos pero son premium. Creo haber leido algo tambien en un "game programming gems" o "ai programming widsom"  (puedes buscar en las tablas de contents de la web para ver si esta en alguno).
En aigamedev hay un articulo sobre potential fields que quizás te http://aigamedev.com/open/tutorials/potential-fields/:

Espero haber sido de ayuda

ADEW!

[EDIT] una pagina con el toc de game programming gems: http://www.asawicki.info/Download/Misc/GameProgrammingGemsTOC.html
#113
Programación gráfica / Re: C++, OpenGL y C#
01 de Febrero de 2011, 08:17:17 PM
Hola,

si lo que quieres es renderizar DX no es excesivamente complicado.
Un buen ejemplo del libro: Game Engine Toolset Development  de Graham Wihlidal,
esta en la web: http://www.delmarlearning.com/companions/content/1592009638/bonus/009638_BonusCh02.pdf
y tb el source: http://www.delmarlearning.com/companions/content/1592009638/codefiles/009638code_AllChapters.exe

Pero si quieres renderizar OpenGl, yo usaria Tao Framework:
wiki:  http://en.wikipedia.org/wiki/Tao_Framework
sourceforge: http://sourceforge.net/projects/taoframework/

Es lo que utilizo yo para renderizar en el editor .NET en windows.

De todas formas es importante el articulo del libro porque te muestra (por encima) como hacer dlls en C++/CLR que hagan de wraper de librerias (.lib) de C++.

Pues nada, espero haber ayudado.
Un saludo.
#114
General Programadores / Control de versiones y Assets
09 de Enero de 2011, 07:31:31 PM
Esta es la eterna pregunta: ¿Como manejar el versionado de los assets de un juego?

Normalmente siempre he utilizado el mismo VCS (Subversion por norma general) que tengo para el código para almacenar los assets.
Pero solo los finales (resultado final de la tuberia de importacion), los binarios que se cargaran directamente por el motor.
Los grafistas y diseñadores se suelen guardar sus propias copias de los documentos (con guardado incremental generalmente) y suelen tener un ftp para subir copias de seguridad. El documento se exporta al binario final, y este es el que incluyo yo en el control de versiones.

Esto me ha funcionado bien en "antiguos" proyectos de PC, moviles e incluso en la DS.
En mi último proyecto de Wii ya me ha costado bastante mantener coherencia en los archivos por el movimiento que representa: el asset va del modelador, al texturizador, luego al animador, y si hay que cambiar algo vuelta para atrás, y en medio estas tu exportando el asset a mitad del desarrollo para que el jefe "vea el muñequito en la pantalla".

Me ha pasado de todo, el grafista te da el fbx exportado y dice haber subido el .max al ftp. Cuando el fbx demuestra algun fallo y se tiene que corregir no se encuentra por ninguna parte el .max original que contenia la ultima version y hay que hacer "maravillas" para solucionarlo, etc, etc, etc.


Ahora todavia es peor, se supone que voy a tener que manejar una cantidad cada vez más grande de assets, y vamos a gestionar una cantidad de datos bastante pesada, que se tiene que ir moviendo arriba y abajo.
Para que la organización sea medianamente aceptable veo totalmente necesario el uso de control de versiones en los documentos binarios (al menos los principales que sirvan de fuente para exportar los assets al motor), con un repositorio (incluso un sistema) diferente del usado para el código fuente.
Para colmo, el editor genera los datos del proyecto, y he de integrar algun tipo de wrapper o front-end para un control de versiones de archivos COLLADA, PSD, .doc, .cls, FBX, DDS, .CG, etc, etc, en el mismo editor.

Las opciones que estoy evaluando:

1) Perforce. El standard de la industria, tan bueno como caro. (creo que paso por el precio) No lo he probado, aunque he oido hablar mucho de él. Segun cuentan las malas lenguas es probablemente el mejor VCS actual, sobretodo si estas trabajando con archvos binarios (desde documentos office, a archivos Maya, pasando por PSDs). Utiliza deltas para almacenar diferencias entre binarios, logrando que las revisiones de los binarios ocupen muy poco espacio (relativamente) en el repositorio, y parece ser extremadamente rápido.

2) Subversion. A mi no me ha ido mal con los binarios, excepto cuando he intentado implantar un sistema completo de versionado de archivos binarios on candados, etc. Generalmente los "no programadores" se vuelven un poco locos. El problema viene al tener muchos archivos, y archivos grandes. Es lento comparado con Mercurial, Git o Bazaar, y el repositorio crece bastante rápido al meter actualizaciones de assets binarios.

3) Mercurial, Bazaar, Git. De entrada son distribuidos, lo que implica que almacenarian una copia de toda la historia de la branch en el "working directory", aunque se pueden podar (al menos en Git) no es la configuracion por defecto. Pienso que para gestionar los assets quizas seria mejor un repositorio centralizado que ir juntando branches, ya que los branches de los binarios ...
Aun asi, se puede hacer que estos sistemas funcionen "emulando" un repositorio centralizado. Mercurial y Bazaar son los más rápidos, si contamos que Git tiene que hacer un "pack" del repositorio, o este crece hasta niveles desmesurados. A pesar de esto ultimo un repositorio de Git  lleno de binarios con cambios en el historial y acabado de "empaquetar" puede llegar a ocupar la mitad que el mismo repositorio en svn. Mercurial y Bazaar generan repositorios ligeramente más pequeños que Svn, aunque no tanto como Git.

4) Gestionar los assets con un sistema propio, ya sea basado en bases de datos, etc. (ni de coña tengo tiempo ahora mismo, ..., y creo que nunca)

5) Big files for ... hay una modificacion (fork) de Git, llamada Git for Big Files, la tengo que probar y medir todavia, pero puede que funcione mejor que Git a secas. Hay otro Big Files para mercurial pero no lo he mirado.


Conclusion:
- Perforce es demasiado caro.
- Svn no es lo mejor para grandes cantidades de datos binarios. Pero tiene soporte para candados.
- Parece que Git se defiende bien, pero tendria que estudiar las posibilidades de configurarlo lo más parecido a un sistema con repositorio centralizado. Es el que produce repositorios más pequeños (aunque haya que hacer un pack del mismo)
- Mercurial y Bazaar son otras dos opciones a estudiar.

- El problema de que dos personas modifiquen "a la vez" un mismo asset y luego intenten subir los cambios creando conflictos, es una cosa que no se como solucionara Perforce, pero que a mi me trae de cabeza (los candados no son siempre la solución), asi que supongo que será cuestión de establecer una "rigurosa" politica de comunicacion y notificación entre el equipo.



¿Opiniones? ¿Sugerencias? ¿insultos?

Bueno gracias a los que lo leais (a los que no, no ;) )
Un saludo
#115
El Quad te viene mejor para terrenos, si tienes ya un buen gestor del terreno, con métodos para descartar la geometria que no ves, no creo que te haga falta.

El tema de las particiones espaciales depende de como lo quieras hacer. El tema es simplificar el coste de comprobación de la visibilidad de un objeto sin tener que comprobarlo contra los planos del frustum de camara (que para una cantidad demasiado grande de objetos en muuu caro).

Yo personalmente trato de manera diferente los objetos estáticos de los dinámicos. La geometria estática corresponderia al "escenario".
Si tienes tu "escenario" como una sola malla (para mi no seria demasiado recomendable) deberias particionarla en "sub-mallas", de igual manera que si estuvieras dibujando "sub-mallas" de un mismo buffer de vertices por que tienes "sub-materiales" (es decir más de un material asociado a un buffer de vertices).
Si quieres que lo haga la construccion del arbol de particion (sea del tipo que sea) tu algoritmo deberia sacar los indices que corresponden a los "trozos" de malla que estas particionando. Aunque en mi opinión seria más conveniente, extraer los vertices (con sus propiedades de uv, etc) y generar nuevos buffers de vertices con las nuevas mallas.

Si quieres gestionar los objetos dinámicos, hay algoritmos un poco más complejos (kd-tree, una modificación del octree que no se como se llama ahora mismo, etc) que te permiten cambiar los objetos de nodos del arbol conforme se mueven, con menor coste que los arboles de particion "tradicionales", aunque y gastaria algun otro tipo de particion, como un "grid" modificable que tampoco recuerdo con exactitud, pero que te puedo decir que esta explicado en un Game Programming Gems (lo siento pero tampoco recuerdo el numero :( ).

Por supuesto, depende de como quieras tener tu scene manager. Si tienes un scene graph "tradicional", puede que todo tu gestor de escena deba de ser un octree, pero tambien puedes poner un octree como "nodo padre" de una serie de mallas u objetos, de manera que al hace el traverse de la escena y encontrar dicho nodo el dibujado de sus "hijos" se haria comprobando la visibilidad con el algoritmo de partición espacial.

No sé si me explico bastante claro, quizás no haya acabado de entender tu pregunta, asi que si te estoy soltando un rollo patatero y no te estoy ayudando dimelo, o concretame las dudas que intentaré ayudarte tanto como me sea posible.

Un saludo, y sigo currando, que con el cierre de la Alpha de aqui unos dias no deberia estar "foreando" ... pero la carne es débil que decia un tio con sotana.

adew
#116
Gracias por los aportes, opiniones y consejos  :)

Pues después de unos cuantos repasos, es como me temia. He aprendido a trazar el código fuente c# a partir del .exe o de una .dll y a modificar las instruciones IL en menos de un dia :(
Me cuesta 0,2segs crackear mi sistema de protección conforme lo tengo ahora. Asi que algo si que me voy a poner las pilas.

La verdad es que es demasiado fácil.

He pensado un par de cosillas y ya van tomando forma, pero la primera y más importante es evitar a toda costa que se modifiquen los assemblies, asi que a "hashear" y a encryptar que toca.

Ya iré contando avances.
Gracias de nuevo.
#117
Programación gráfica / Re: Novato con OpenGL
27 de Noviembre de 2010, 06:02:52 PM
No creo que tengas problema en meter eventos de llamada desde Objective-C a C++, por lo que elegir C y no usar la orientación a objetos me parece una decisión propia o de gusto, no de especificación (es mi opinión).

En cuanto a OpenGl, lo veo titánico si quereis meter skinned meshes (personas que andan) y ir juntando cachillos de código para cargar mallas y todo el tema. También esta si te implementas algun tipo de gestor de escena y todo el rollo (controlar y optimizar cambios de estados openGl, mantener el control de los assets, ...). Sobretodo si no teneis mucha experiencia.

En cuanto a formatos, ya puse mi opinión este hilo: http://www.stratos-ad.com/forums/index.php?topic=13202.msg140567#msg140567
Aun asi, obj no te serviria para modelos con skin, porque no exporta animaciones ni informacion de rigging o bones.
Si quieres aniamacion por vertice en vez de por bones md2 creo que era el ultimo decente que utilice, si quieres bones los formatos má actuales lo tienen casi todos.


Pero mi consejo es que cojais ogre para iPhone o algun otro motor (Unity esta muy bien y es realmente sencillo), asi podreis dedicarle más tiempo a la jugabilidad y a pulir detalles que a la tecnologia, y (en mi opinión) os quedara un juego más chulo.
Si lo que quereis es aprender adelante, pero puede que el juego sufra más en algunos aspectos.
Si lo que quereis es hacer tecnologia "solida" para luego reutilizar y mejorarla, mirar el mensaje que indico arriba, tb tiene un enlace a un articulo de gamasutra muy interesante.


Pues nada, espero haber ayudado, un saludo.
#118
Programación gráfica / Re: qué librería uso?
27 de Noviembre de 2010, 05:49:34 PM
Si quieres hacer un editor, y tienes poco tiempo: C# WinForms
Es rápido de desarrollar, y bastante sencillo y potente. Puedes gastar GDI+ o Managed DX para dibujar. El primero solo 2D, en un principio.

El tema es que puedas editar gráficos "vectoriales" en 2D que seria la representacion con la que trabajarias ¿no?
Luego debes covertir los datos "vectoriales 2D" a datos "vectoriales 3D" y dibujarlos en un visualizador ¿me equivoco?

No sé como va el tema XNA ahora, ya hace tiempo que no lo toco. Pero hacerte un visualizador 3D en un Componente o Control de Winforms, es realmente sencillo.
El problema vendria si quieres hacer varias ventanas de visualización. Sigue siendo tan facil como arrastrar tu Control al formulario que quieras, pero creo que no puedes configurar las chains de directX, y tendrias que tner un device para cada ventana (lo único en lo que puede influir es en el rendimiento del dibujado, pero para lo que quieres hacer no debe ser un problema).

Bueno, espero haber sido de alguna utilidad,
un saludo y suerte.

PS: por cierto Mortdegana, come algo que te se ve flacucho :P
#119
Hola,
siguiendo el consejo de Hechelion estoy investigando la forma de "romper" yo mismo la protección de mi software para poder mejorarla.

Lo primero que he encontrado es el Reflector y el FileDisassembler. Con el que puedes ver e incluso trazar en el visual studio cualquier .NET, .exe o .dll, a nivel de código fuente (C# en este caso). Lo único que no se todavia como hacer es modificar el ensamblado, pero darme un dia más que esto parece (y ojala me equivoque) que coser y cantar  >:(

Si no seria muy complicado sustituir un "jne" por un "je" en ensamblador ni te cuento como de facil es leer o trazar el codigo fuente C# y encontrar lo que buscas, sobretodo si se trata de modificar un par de comparaciones.

Lo primero que tengo en mente es utilizar ofuscadores de código, ya lo utilizaba bastante cuando haciamos juegos de moviles en java, e incluso a veces desensamblabamos el propio código ofuscado, ya que algunos parches para algun movil especifico como meter una llamada a un clase unica de ese modelo, sin tener la libreria y cosas de ese estilo.
La verdad es que funcionan de una forma muy parecida a los que utilizaba para java, pero con la diferencia aquel código ofuscado y decompilado, raramente podia compilarse de nuevo otra vez como java, y tenias que modificar y "reconstruir" parte del código, y si no estabas muy relacionado el byte-code de java, puede que no supierascomo hacerlo o las pasaras canutas (como yo).
Esto parece, sin embargo, y a mi pesar, mucho más fácil  :grrr:

Tambien he leido que hay una manera de que visual studio encripte tus dlls, y que solo con una clave puedas decriptarla, pero una vez el usuario final tenga la clave, no se que le impediria utilizar reflector, por ejemplo.

Por último, el tema de comprimir o encriptar parte del código ... no se me ocurre como, no se si el código CLI o como se llame se puede encriptar/comprimir, y luego hacer el procedimiento inverso y ejecutarlo.
Lo único que posiblemente se pueda hacer, o pueda funcionar, es tener código "crítico" para la ejecución del programa en C# en un archivo encriptado y en tiempo de ejecución desencriptarlo y compilarlo / ejecutarlo JIT. Pero no se donde meter la clave, si la pongo en código se puede trazar, si la pongo el registro tambien, si la pongo en un archivo por supuesto, y si la encripto necesito otra clave para desencriptarla (nananana, arrrrggg!)  |:|


La verdad es que me asusta bastante esta "desproteción" del software, que para mi parece demasiado flagrante, y aunque sé que todos los lenguajes se pueden "crackear" esto me parece excesivo. El coste de la versatilidad y potencia de la reflexión en .NET aqui parece una de las mayores amenazas para la seguridad de tu producto.
Pero bueno, tengo la mayor parte de la funcionalidad del editor en C#, y la verdad es que me ha costado menos de la mitad que si la tuviera que haber hecho en C++, asi que no voy a cambiar a estas alturas de lenguaje.

Si alguien puesto en .NET me pudiera tranquilizar (aunque solo fueran un par de mentiras piadosas) quizás acabará antes de "rallarme" con todo este tema, y vuelva al código de funcionalidad del programa. (please)


Bueno, un saludo y gracias.

EDIT: otra cosa que estoy pensando es realizar crc o hash de los assemblies que contienen la proteccion, y comprobarlos en otras partes del programa, o utilizar el resultado como clave asimetrica para encriptar algo, todavia estoy cociendo la idea. No es un obstaculo insuperable, pero puede dar bastantes dolores de cabeza al que intente modificar un assembly. ¿alguna opinión al respecto?
#120
Muchas gracia por la explicación :)

Por ahora solo tengo en mente un par de posibles clientes para un par de proyectos.
Asi que la aplicación no deberia ir de manos en manos, y seguramente serian los mismos clientes los que se asegurarian de que la aplicacion por la que pagan la licencia no sale a terceras personas que pudieran aprovecharse de algo que solo ellos deberian tener.

Asi que solo me preocupan los "clientes", que, como es habitual, si pueden pagar 10 en vez de 20 no se lo piensan, aunque esos 10 fueran a parar a alguien contratado para "modificar ilegalmente" el programa, en vez de al desarrollador original del software. Y que quede claro que siempre he defendido compartir código y el open source, pero depués de ver como diferentes empresas hacian grandes cantidades de dinero a costa del trabajo y esfuerzos de "asalariados", no tengo ninguna gana de lo que sigan haciendolo a la mia, puesto que aqui ya no cumplo el papel de "asalariado".

Mi intención (y espero que asi sea, o muy mal me irá) es que el "engine" en si, vaya creciendo y evolucionando en cuanto a plataformas destino y features, de manera que puedo controlar que sean "necesarias" ciertas actualizaciones, y que las versiones anteriores del software queden, por necesidad, obsoletas. Lo cual me puede ayudar a ir integrando un sistema de proteccion cada vez más complejo, o, al menos, ligeramente modificado, por si la versión anterior ya ha sido reventada.

Por supuesto no pienso dedicarme al software antipirateria ya que ni siquiera me considero experto en lo que hago (y eso que cada dia se me hace más dificil recordar cuantos años llevo ya en esto), asi que ni decir tengo de meterme en algo en lo que estoy completamente pez (ahora mismo no veo capaz ni de desbordar un buffer).

El tipo de aplicación que estoy realizando no creo que sea la indicada para un público extenso, y, en caso de que compañias más "importantes" quisieran utilizar mi producto, he de decir que me fio más de ellas (por irónico que parezca), que algunas de las más "pequeñas" que ahora mismo puedan estar interesadas en mi producto. Simplemente por el echo de que el dinero de las licencias "se la pela" literalmente.
Cuando he currado en una empresa "multinacional" o una empresa "grande" hemos tenido licencias legales de todo el software, incluso licencias de sobra guardadas en un cajón y cogiendo polvo. Más tarde he llegado a una empresa más "modesta" como Lead Programmer y me han tenido con un portatil basura durante dos o tres semanas (perdiendo tiempo de productividad) por no gastarse el dinero en un PC (entre otras muchas barbaridades).

Asi que lo que me preocupa, una vez más, es que alguien pueda gastarse dinero en saltarse el if, con tal de salirse con la suya y no pagar el mismo dinero o un poco más a mi, que al fin y al cabo, soy el que ha perdido montones de horas de sueño y vida social.

En cuanto al tema se los serials / bulk, las fechas de activación, etc lo he implementado como técnica disuasoria. Primero, es fácil de implementar, simplemente se basa en encryptar/desencryptar texto con la informacion de la licencia, comprobar las fechas y las features de la version activada.
Si alguien no versado en el tema ve los cuadros de dialogo y que no puede iniciar la aplicacion, puede frenarle la idea, antes incluso de intentar averiguar realmente como esta implementada la protección. Por supuesto, alguien que tenga idea tardaria 0'01 seg en reventarlo.

Como tengo mucho más que implementar de la parte funcional del software, no puedo dedicarle mucho más tiempo a esto, pero aun asi Hechelion me ha interesado mucho el tema de la protección que implementas tú cifrando parte del código necesario, si fueras tan amable de recomendarme un par de enlaces donde pueda intentar ilustrarme sobre el tema te estaria muy agracedio, más que nada por intentar mejorar un poco (solo lo suficiente) el sistema de protección.

Y por cierto, y ya que veo que estas muy puesto en el tema, también me suelo preguntar como se puede demostrar que una aplicación (pongamos un juego de ps3,  por ejemplo) ha sido realizado con tu sdk o engine. ¿Analizando los binarios para encontrar los patrones de tus librerias por ejemplo?
Es otra cosa que me ronda la cabeza, como ves últimamente me estoy volviendo un poco paranoico, XD

Bueno, muchas gracias de nuevo.
Adew!

EDIT:
en cuanto a crear varios timers me parece una idea estupenda, asi que voy a intentar ponerme con ello cuando antes,  :D thank you!
Por cierto, cuando hablas de no utilizar una única función, ¿te refieres que seria mejor tener varias funciones que hagan lo mismo o algo parecido y cada vez que "salta" un timer llamar a una de ellas?
Bien pensado tiene sentido que si averiguas la dirrecion de la funcion que hace el check, te seria, más o menos sencillo, buscar las zonas donde se llama a la misma direccion, ¿no?





Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.