jueves, 28 de agosto de 2008

El futuro...

El futuro no esta escrito que diría Sara Connor... pero desde luego esta muy negro...

Me gustaría que el avance de Sindarin fuese en esta dirección:
  1. En las versiones actuales de Sindarin poner el modo Nativo desactivado por defecto.
  2. Corrección de los diversos Bugs: En especial el bug que no impide la correcta llamada a otro script con parámetros.
  3. Mejorar el mecanismo de ejecución parada del script.
  4. Mejorar las capacidades de edición de Script.
  5. Independizar la GUI del sistema sobre el que corre.
  6. Eliminación del modo nativo: La arquitectura de Sindarin no estaba pensada para el modo nativo, este fue un añadido a ultima hora, y por las características del Api de win32, nunca podrá funcionar como debiera, así que creo que se convertido mas en un engorro que en una utilidad. Por otro lado el desconocimiento me ha impedido reescribirlo en linux, lo que tiene muchas e importantes consecuencias negativas alrededor de la portabilidad y usabilidad del programa bajo linux. Ademas se que nadie lo usa, así que nadie lo echara de menos en Sindarin.
  7. Implementación de Sindarin Lite: Aunque de la versión "grande" de Sindarin se elimine el modo Nativo, estaría bien poder diseñar he implementar un Sindarin "reducido" exclusivamente diseñado para funcionar en modo Nativo, lo que implicaría que este fork de momento seria inviable bajo linux.
  8. Reimplementacion del ScriptParser y CodeInterpreter: Para lograr que ambos módulos puedan trabajar de forma completamente independiente el uno del otro, de forma que se puedan usar por ejemplo distintas versiones de esos módulos sin que eso afecte al resultado final de forma negativa o que el GUI pueda ser independiente. La idea es conseguir que funcionen como un programa típico de linux:

    $ScriptParser script.sdr > salida.txt
    $CodeInterpreter salida.txt
    
    o bien:

    $ScriptParser script.sdr > CodeInterpreter
    
    de forma que el GUI únicamente seria la forma interactiva de llamar a ambos módulos.
  9. Escritura de un nuevo GUI: Un GUI esencialmente más atractivo y con una funcionalidad similar o superior. Me gustaría darle un aspecto similar a este: Aunque también se podría estudiar la forma de permitir diversidad de Skins.
  10. Implementación del comando "Component": Comando que permitiría el análisis de los componentes [R, G, B] de las variables "Color" y [X, Y] de las variables "Location" por separado, de forma que podamos saber directamente si el punto que analizamos es efectivamente mas o menos verde o saber en que coordenada X se encuentra exactamente nuestro ratón.
  11. Implementar la sentencia "switch": Para poder hacer scripts con muchas decisiones, mas elegantemente.
  12. Leer variables directamente del cliente: Realizar otro fork o modulo de ampliación que permita leer las variables directamente del cliente, como hace EasyUO, pero esto no puede ser una característica "base" de Sindarin, porque hay shards que no permiten los asistentes que leen directamente del cliente, así que debe ser posible no estar activa por defecto.
  13. Implementar un modulo de búsqueda y de patrones graficos: De forma que podamos buscar sobre la imagen cosas como la mochila o el paperdoll o cualquier cosa que nos de la gana, aunque si esta disponible la lectura de variables de cliente quizás esta ampliación o modulo sea redundante.
  14. Realizar una versión ejecutable de Sindarin que sea un fichero EXE, ya que por alguna razón a la gente le resulta complicado hacer funcionar un JAR.
  15. Utilizar la Api de java de internacionalización: Para que al menos el GUI este en varios idiomas y quizás implementar el lenguaje script de tal forma que hasta los comandos estén el el idioma natal del usuario, aunque esto habría que estudiarlo por las repercusiones a la hora del entendimiento e intercambio de scripts entre personas que podría tener.
Pero... La triste realidad es que no tengo tiempo, ni colaboración para hacer nada de esto, por eso el futuro de Sindarin es muy negro, a menos que me despidan o me vuelva loco y use todo mi tiempo libre para Sindarin. Otra posibilidad seria que alguien que supiese de programación y preferentemente de Java o estuviese dispuesto a hacer el esfuerzo, comenzara a colaborar conmigo, en ese caso quizás me plantearía volver a coger el proyecto con fuerza.

miércoles, 27 de agosto de 2008

Explicación exhaustiva...

Finalmente el ultimo texto rescatado del baúl de los recuerdos:

Sintaxis de Sindarin en formato BNF y explicación exhaustiva de los comandos (revisado).

También puede interesarte:



  1. El comienzo...
  2. Códigos...
  3. Lista de todos los comandos
  4. wait
  5. iodelay
  6. say
  7. keypress
  8. keyrelease
  9. pushkey
  10. click
  11. dclick
  12. mousemove
  13. mousepress
  14. mouserelease
  15. drag
  16. if
  17. while
  18. repeat
  19. break
  20. exit
  21. print
  22. beep
  23. date
  24. time
  25. call
  26. igualación
  27. declaración de variables
  28. Expresiones aritméticas y booleanas
  29. Miscelánea


  1. El comienzo...

    Un programa Sindarin consta de dos partes, definición de variables y códigos, ambas opcionales.
    La declaración de variables debe hacerse obligatoriamente al principio del script.

    La definición BNF es:

    { declaración de variables } {códigos... }
  2. códigos...

    Esta parte estará compuesta por un comando seguido o no por un ";" o una lista de comandos encerrados entre corchetes "{" "}" o palabras claves "begin" "end".

    La definición BNF es:

    comando [";"] | "{" {state [";"]} "}" | "begin" {state [";"]} "end"
  3. Lista de todos los comandos

    Más abajo se detallan pormenorizadamente cada uno de los comandos aquí una enumeración de todos los comandos:


    • wait: Ejecuta una pausa en la ejecución.
    • iodelay: Modifica la pausa automática que se realiza tras cada comando de entrada/salida de teclado o ratón.
    • say: El pj dice algo.
    • keypress: pulsa una macro y la mantiene pulsada.
    • keyrelease: libera la pulsación de una macro.
    • pushkey: pulsa una macro y la suelta, equivalente a click para el teclado.
    • click: Simula un click en un punto de pantalla.
    • dclick: Simula un doble click en un punto de pantalla.
    • mousemove: mueve el cursor del ratón a una posición de pantalla.
    • mousepress: un botón del ratón y lo mantiene pulsado.
    • mouserelease: libera la pulsación de un botón del ratón.
    • drag: mueve una cantidad de objetos desde una localización a otra.
    • if: hace un comprobación y ejecuta un código si esta es cierta o no sino lo es.
    • while: repite el/los códigos que están a continuación mientras se cumpla una condición.
    • repeat: repite el comando o los comandos encerrados entre "{","}" o "begin", "end" tantas veces como indique la expresión numérica puesta a continuación.
    • break: Sale de un bucle repeat o while en caso de encontrarse dentro de uno.
    • exit: Termina el programa.
    • print: Imprime en la consola de mensajes la expresión puesta a continuación.
    • beep: Emite un sonido de alerta.
    • date: Introduce en las variables colocadas a continuación el día, mes y año actual, según la fecha del equipo.
    • time: Introduce en las variables colocadas a continuación la hora, minutos y segundos de la hora del sistema.
    • call: Ejecuta otro script Sindarin.
    • Aunque no es un comando propiamente dicho si se coloca una variable seguida de "=" se introduce en ella el valor de la expresión siguiente.
  4. wait (esperar...)

    Realiza una pausa en la ejecución del programa.

    La sintaxis es: "wait" seguido de una expresión numérica que indica la cantidad de tiempo a pausar,
    seguida de la unidad de tiempo.

    Las unidades de tiempo se miden en minutos "min", segundos "sec" y milisegundos "milisec" "msec", en caso de no especificar ninguna se supondrá que la unidad de tiempo es el segundo.

    La definición BNF es:

    wait expresión_numérica ([sec] | min | milisec | MSEC)
  5. iodelay (retrazo de entrada salida)

    Las instrucciones de entrada salida(mousepress, click, pushkey...) realizan automáticamente un pausa al terminar
    , por defecto esta pausa es de 4 milisegundos, con este comando esta cantidad se puede variar usando este comando.

    La sintaxis es: "iodelay" seguido de una expresión numérica que indica la cantidad de tiempo a pausar,
    seguida de la unidad de tiempo.

    Las unidades de tiempo se miden en minutos "min", segundos "sec" y milisegundos "milisec" "msec", en caso de no especificar ninguna se supondrá que la unidad de tiempo es el segundo.

    La definición BNF es:

    iodelay expresión_numérica ([sec] | min | milisec | msec)
  6. say (decir)

    Esta instrucción hace que el PJ diga algo en el Ultima Online. La sintaxis de esta instrucción es say seguido de una expresión de texto.

    La definición BNF es:

    say expresión_textual
  7. keypress (Presiona tecla)

    Simula la pulsación de una o varias teclas especificadas por una expresión de tipo Macrokey(macro de tecla),
    este comando no realiza la liberación de la tecla, es decir mientras no se llame al comando Keyrelease con la misma expresión de tecla o bien a un comando de tipo
    Pushkey, que realiza un pulsación y luego la liberación, sobre el mismo conjunto de teclas.

    Este comando puede escribirse además de las siguientes maneras: kpress.

    La definición BNF es:

    keypress expresión de tipo tecla
  8. keyrelease (Libera tecla)

    Simula la liberación de una o varias teclas que se encuentren pulsadas por la llamada a un comando Keypress, este comando es el complementario de Keypress.

    Este comando puede escribirse además de las siguientes maneras: krelease, krel.

    La definición BNF es:

    keyrelease expresión de tipo tecla
  9. pushkey (pulsar tecla)

    Simula la pulsación y posterior liberación de una o varias teclas, es como llamar consecutivamente a Keypress y luego a Keyrelease sobre el mismo conjunto de teclas.

    Este comando puede escribirse además de las siguientes maneras: pkey, key.

    La definición BNF es:

    pushkey expresión de tipo tecla
  10. click

    Realiza la simulación de un click del ratón sobre un punto especifico de la ventana, es equivalente a
    realizar un Mousemove, seguido de un Mousepress y un Mouserelease con el mismo botón y sobre la misma localización.

    La definición BNF es:

    click (left | right) expresión de tipo Location(Localización de pantalla)
  11. dclick

    Realiza la simulación de un doble click del ratón sobre un punto especifico de la ventana, es equivalente a
    realizar dos click consecutivos el mismo botón y sobre la misma localización.

    Este comando puede escribirse además de las siguientes maneras: doubleclick.

    La definición BNF es:

    dclick (left | right) expresión de tipo Location(Localización de pantalla)
  12. mousemove (mover ratón)

    Este comando mueve el cursor del ratón desde su posición actual hasta la posición indicada a continuación.

    Toda la familia de comandos Mouse...(Mousemove, Mousepress y Mouserelease) tienen problemas en modo nativo,
    si se usan con la ventana de Ultima maximizadas. Para evitar estos problemas lo mejor es minimizar la ventana de Ultima o bien
    desactivar el modo nativo.

    Este comando puede escribirse además de las siguientes maneras: mmove.

    La definición BNF es:

    mousemove expresión de tipo localización
  13. mousepress (presiona ratón)

    Este comando simula la pulsación del botón colocado a continuación del comando, pero no su liberación,
    por lo que permanece pulsado hasta que se ejecute el comando Mouserelease sobre dicho botón o un comando
    de tipo click o dclick que implícitamente realizan un Mouserelease.

    Toda la familia de comandos Mouse...(Mousemove, Mousepress y Mouserelease) tienen problemas en modo nativo,
    si se usan con la ventana de Ultima maximizadas. Para evitar estos problemas lo mejor es minimizar la ventana de Ultima o bien
    desactivar el modo nativo.

    Este comando puede escribirse además de las siguientes maneras: mpress.

    La definición BNF es:

    mousepress (left | right)
  14. mouserelease (Libera ratón)

    Este comando simula la liberación de un botón que a sido atrapado usando el comando mousepress, este comando es su complementario.

    Toda la familia de comandos Mouse...(Mousemove, Mousepress y Mouserelease) tienen problemas en modo nativo,
    si se usan con la ventana de Ultima maximizadas. Para evitar estos problemas lo mejor es minimizar la ventana de Ultima o bien
    desactivar el modo nativo.

    Este comando puede escribirse además de las siguientes maneras: mrelease, mrel.

    La definición BNF es:

    mouserelease (left | right)
  15. drag

    Este comando sirve para mover una cantidad de objetos desde una localización a otra. Debe ir seguido de una expresión numérica
    que indique el numero de objetos a mover, pudiendo ir seguido de la palabra "objets" que no cumple ninguna finalidad y es prescindible,
    una expresión de tipo localización que indique donde se encuentran en principio los objetos, que puede
    ir seguida de la palabra "from", que también es prescindible, y otra m que indique donde hay que soltarlos.

    La definición BNF es:

    drag expresión numérica [OBJECTS] expresión de tipo location(Localización) [FROM] expresión de tipo location(Localización)

    Desde la versión 0.3, se ha añdido la opción de usar "ALL" en lugar de una cantidad a mover lo que mueve todos los objetos.

    La definición BNF es:

    drag [ expresión numérica| ALL ] [OBJECTS] expresión de tipo location(Localización) [from] expresión de tipo location(Localización)
  16. if

    "If" evalúa una expresión colocada inmediatamente después, si esta expresión es 0 supondrá que es falsa y no se ejecutaran las sentencias colocadas a posterioridad,
    si la expresión es distinta de 0 se ejecutara la/las sentencias colocadas a continuación.

    La sentencia If puede ir seguida de la clausula "else", si la expresión evaluada por if es falsa entonces se ejecutara la/s sentencias colocadas a continuación de else.

    Existen las variables de entorno true y false, cuyo valor es respectivamente 0 y 1, con lo cual una sentencia del tipo: "if true { comandos 1 } else { comandos 2 }" ejecutara siempre
    "{ comandos 2 }" mientras que la sentencia: if false { comandos 1 } else { comandos 2 }" ejecutara siempre "{ comandos 2 }".

    If espera evaluar siempre una expresión numérica, por lo tanto se pueden usar cualquiera de los operadores aritméticos que se contemplan en las expresiones normales, sin embargo existen
    una serie de operadores especí­ficos pensados para las sentencias de evaluación(aunque pueden insertarse en cualquier expresión aritméticos normal).

    La definición BNF es:

    if expresión booleanas ( { comandos } | begin comandos end | comando ) [ else ( { comandos } | begin comandos end | comando ) ]
  17. while (mientras)

    Este comando permite ejecutar varias veces un digo colocado a continuación, la lógica de este comando es la siguiente: mientras la expresión booleana colocada a continuación sea verdadera se continuara ejecutando
    lo/s comandos colocados inmediatamente después. Así por ejemplo seria posible construir un bucle infinito de la siguiente manera: "while true { comandos }" que significar que mientras true(verdadero) sea verdadero entonces se ejecutar
    "{ comandos }" puesto que true siempre es verdadero "{ comandos }" se ejecutar para siempre.

    Otro ejemplo de construcción valida seria:

    while (color [100, 100] = color1)
    say "hola"
    

    lo que obligar al jugador a decir "hola" mientras el color de la Location [100, 100] fuese distinto de la variable color1.

    La definición BNF es:

    while expresión booleana sea cierta ( { comandos } | begin comandos end | comando )
  18. repeat (repetir)

    Este comando permite ejecutar varias veces un digo colocado a continuación, la lógica de este comando es la siguiente: repetir un numero finito de veces, especificado en una expresión numérica, el digo colocado a continuación.

    Un ejemplo de construcción valida seria:

    Number a = 50;
    repeat (a/2) times
    say "hola"
    
    lo que obligar al jugador a decir "hola" 25 veces.

    Otro ejemplo de construcción valida seria:

    repeat 100
    begin
    drag 1 object [100,100] from [200,200]
    end
    
    Que obligar a mover un objeto desde la posición [100,100] hasta la [200,200] cien veces consecutivas.

    Otro ejemplo de uso seria:

    repeat 10
    {
    pushkey 'F1'
    wait 1 min
    }
    
    Que obligar a pulsar 'F1' 10 veces con un retraso de un minuto entre pulsación y pulsación.

    La definición BNF es:

    repeat expresión numérica [times] ( { comandos } | begin comandos end | comando )
  19. break (Romper)

    Interrumpe la ejecución de un bucle, si colocamos break dentro de un bucle y se alcanza el break, se sale del bucle.

    Un ejemplo de utilización seria:

    while (true) {
    say "hola"
    break
    }
    
    El "hola" solo se ver una vez ya que al llegar al break se terminar el bucle infinito.

    Otro ejemplo de uso seria:

    Location nightshade = [100, 100]
    Color verde = [0, 255, 0]
    repeat 10000
    {
    pushkey 'a'
    wait 1
    if (verde != color nightshade)
    break
    }
    Este bucle pulsar diez mil veces la tecla 'a', a menos que la Location "nightshade" no tuviera el color "verde".

    La definición BNF es:

    break
  20. exit (salir)

    Si durante la ejecución de un código se encuentra el comando "exit" se termina la ejecución, es como si se le hubiese dado al botón de "Stop".

    La definición BNF es:

    exit
  21. print

    Imprime en la consola de mensajes la expresión siguiente.

    La definición BNF es:

    print expresión
  22. beep

    Emite un sonido de alerta.

    Disponible desde la versión 0.3

    La definición BNF es:

    beep
  23. date (fecha)

    Este comando carga en tres variables/parametros pasados entre parentesis y separados por comas, la fecha del sistema.

    En el primer var/parametro numérico de la función se mete el año del sistema, en el segundo el mes y en el tercero el día.
    La definición BNF es:

    date "(" año "," mes "," día ")"
  24. time (hora)

    Introduce en los tres parametros variables siguientes la hora del sistema, estos parametros han de estar entre parentesis y separados por comas.

    La definición BNF es:

    time "(" hora "," minuto "," segundo ")"
  25. call

    Ejecuta otro script de Sindarin, el script se define con una cadena de texto tras el comando call que contendrá el camino al fichero, el script llamador puede enviar parámetros al script llamado.
    Los parámetros han de pasarse entre parárentesis y separados por comas, solo es posible pasar literales, variables o parámetros, las expresiones complejas no están permitidas como parámetro. Si el parámetro pasado es una variable o un parámetro, las modificaciones que se realicen dentro del script llamado tendrán efecto en las variables del llamante.

    Dentro del script se referencia los parámetros como "$" seguido de un numero, de forma que "$1" seria el primer parámetro pasado, "$2" el segundo, no existe limitación en cuanto a el número de parámetros.

    Hay que tener precaución en tanto en cuanto no se hace ninguna comprobación del tipo de parámetro pasado, es decir si el script llamante pasa un numero 1 y el script llamado esperaba un texto no se emitirá error hasta el momento de usar el parámetro, pudiendo darse el caso de que no se emita error debido a que el contexto de uso permita el uso de distintos tipos de variables, aunque evidentemente funcionara mal.
    Tampoco se realiza una comprobación del numero de parámetros por lo que se podrá llamar a un script que esperase 3 parámetros sin ninguno, lo que emitirá un error en el script llamado.

    Este comando puede escribirse además de las siguientes maneras: @

    La definición BNF es:

    call "camino hasta el script" ["("lista de parametros separados por comas")"]
  26. igualación

    Operador de igualación, colocamos una variable de cualquier tipo seguida de símbolo "=" y de una expresión del mismo tipo que la variable/parametro y esta toma el valor dado por la expresión.

    La definición BNF es:

    (variable | parametro) = expresión
  27. declaración de variables

    Las variables tienen un nombre y un valor, el nombre a de comenzar por "_" o letras y a de ir seguido por una o mas letras, dígitos y "_"
    La declaración de variables se ha de realizar obligatoriamente al principio del script. Los distintos tipos de variables son los siguientes:

    • Number: son aquellas variables que pueden tomar valores numéricos de tipo entero, superiores a 0. Ejemplo:

      Number a=1, b=2
      Number c = a + b
      
    • String: son variables que pueden tomar valores de tipo textual encerradas entre ". Ejemplo:

      String nombre_vendedor = "marlon";
      String comprar = nombre_vendedor + " buy";
      
    • Location: son variables que toman posiciones de pantallas, representadas en dos coordenadas X e Y, encerradas entre [] y separados por comas. Ejemplo:

      Location localizacion_mochila = [100, 100];
      
    • Macrokey: son variables que pueden tomar valores entre una y cuatro teclas, donde cada una de las teclas se han de encerrar entre ' y para aumentar el numero de teclas representadas en una macrokey han de ser sumadas, un ejemplo de declaración:

      Macrokey pulsar_f1_y_f2 = 'f1' + 'f2'
      
      Puesto que salvo las teclas simples (números y letras) las demás se representan por una cadena de texto es especialmente y recomendable usar las facilidades de inicialización de Sindarin
    • Color: representa un color de pantalla, el color debe especificarse en formato RGB, donde cada una de las componentes han de estar encerradas entre [] y separadas por comas. Un par ejemplos de declaración e inicialización son:

      Color rojo = [255, 0, 0];
      Color color_mochila = color localizacion_mochila;
      
      
      
    La definición BNF es:

    ( number | string | location | macrokey | color ) nombre_var1 [ "=" expresión de inicialización ]] {"," nombre_varN [ "=" expresión de inicialización ]]} [";"]
  28. Expresiones aritméticas y booleanas

    Sumas, restas...
    Operadores Aritméticos:

    • "+": Suma dos operadores: Es posible sumar cualquier variable con cualquier variable, siempre que sean del mismo tipo, salvo las variables de tipo String que al ser sumadas con cualquier otra producen un resultado de tipo String.
      Las variables de tipo Location, y color al ser sumadas se suman como si se sumaran elemento a elemento cada una de sus componente, es decir la Location [100, 100] + [50,50] crearían una Location [150,150].
      Al sumar colores si el rango de cualquier suma sobrepasa el 255, que es el máximo rojo o verde o azul, es decir si sumamos [255, 255, 255] + [1 ,1 ,1], esto sobrepasaría el limite máximo, así que se redondea a [255, 255, 255].
      Las variables tipo Macrokey generan una Macrokey tal que al pulsarla seria como pulsar las dos sumadas a la vez: ejemplo:

      Macrokey a = 'a'; a = a + 'F1'; pkey a;

      Esto generaria una pulsación de 'a' y 'F1' a la vez.
    • "-": Resta dos operadores: También es posible restar cualquier variable con cualquier otra del mismo tipo, excepto las de tipo String, esas no es posible restarlas con nada.
      Igualmente tanto Locations como Colors se restan componente a componente.
      Si una componente de un Color al restar llegase a un numero negativo: [0,0,0] - [1,1,1], el resultado se redondearía a [0,0,0].
      Las variables de tipo Macrokey al restar una a otra genera una macrokey como el primer operador pero sin la/s teclas del segundo, en caso de que la/s teclas del segundo no existiesen en el primer operando no se hace nada:

      Macrokey a = 'F1'+'F2';
      Macrokey b = a -'F2';
      Macrokey c = a -'F3';
      key a
      key b
      key c
      

      Al pulsar a se pulsarían simultaneamente la tecla 'F1' y 'F2', al pulsar b se pulsaría solo 'F1' y al pulsar c se pulsaría de nuevo 'F1' y 'F2'

    • "*": Multiplica dos operadores, solo es posible multiplicar Números con Números.
    • "%": Calcula el modulo de dos operandos, solo es posible calcular el modulo de dos números.

    Es posible realizar operaciones del tipo:

    Number a = 1 + 2 * 3 + 8 * (15 + 1)/2
    Number b = (1 + 2)*((a + 8)*(15 + 1)/sindarin_version)
    String c = "hola " + Manolito + 15
    Location d = [100, 100] - [25,25] + [10,10]
    

    Nótese que en a se calcularía 1 + (2 * 3) + (8 * (15 + 1)/2) dado que el orden de precedencia de los operadores *, / y % son los esperados.
    Y como podemos ver en b se pueden usar variables predefinidas en los cálculos.

    Evaluación de condiciones:

    Operadores relacionales:

    • "<" operador "menor que", devuelve true si la expresion inmediatamente anterior es menor que la siguiente a el.
    • ">" operador "mayor que", devuelve true si la expresión inmediatamente anterior es mayor que la siguiente a el.
    • "<=" operador "menor o igual que", devuelve true si la expresion inmediatamente anterior es menor o igual que la siguiente a el, tambi puede escribirse como "=<".
    • ">=" operador "mayor o igual que", devuelve true si la expresión inmediatamente anterior es mayor o igual que la siguiente a el, también puede escribirse como "=>".

    Estos operadores solo pueden evaluar expresiones numérica, cualquier otro tipo de expresión emitirán error.

    Sin embargo existen las dos siguiente expresiones:

    • "=" operador "igual que",devuelve true si la expresión colocada antes del "=" es igual a la colocada después, también puede escribirse de la siguiente manera: "==".
    • "!=" operador "distinto de", devuelve true si la expresión colocada antes del "!=" es distinta a la colocada después, también puede escribirse de la siguiente manera: "<>".

    Estos dos operadores pueden aplicarse a cualquier tipo de expresión.

    Existen también operadores booleanos que permiten relacionar varias expresiones entre si:

    • "&" operador "Y", devuelve true si las expresiones colocada a ambos lados son verdaderas(distintas de 0) y devuelve false en el caso de que alguna de las dos fuese falsa. Puede escribirse "&&" y "and"
    • "|" operador "O", devuelve true si alguna de las expresiones colocada a ambos lados es verdadera(distintas de 0) y devuelve false en el caso de que ambas sean falsas. Puede escribirse "||" y "or"

  29. Miscelánea


    • Comentarios: los comentarios han de comenzar por el carácter #, el resto de la linea sera ignorado por Sindarin
    • isnativemode: Puede usarse dentro de una expresión, devuelve true si esta funcionando correctamente el modo nativo, ejemplo:
      if (isnativemode == false) print "A ocurrido algún error con la ventana de Ultima". También puede escribirse isnatmode.
    • Color: Además de usarse para definir el tipo Color también sirve para saber que color una localización precisa, ejemplo:

      if (color loc1 != [1,1,1]) say "a cambiado el color"

      Con la ventana minimizada no funciona, ni siquiera
      en modo nativo,es necesario que el punto a evaluar
      este en primer plano.
    • Component: se usa para poder diferenciar cada uno de los componentes básicos de colores o localizaciones, ejemplo:

      Location barra_vida = [358, 325];
      Color c = Color barra_vida;
      Number verde = component 2 c
      
      while (verde < 125) {
      c = Color barra_vida
      verde = component 2 c
      print "No estamos muy verdes"
      }
      print "SuperVerdes"

    • true: es una variable predefinida con el valor 1, para facilitar el uso en comandos de evaluación, ejemplo:
      while (true) say "Siempre se ejecuta..."
    • false: es una variable predefinida con el valor 0, para facilitar el uso en comandos de evaluación, ejemplo:
      if (false) print "nunca llega" 
    • sindarin_version: variable predefinida de tipo Number, que contiene el numero de la versión de Sindarin corriendo en el momento, ejemplo:
    • if sindarin_version < 1 print "Esta version no es definitiva"
    • sindarin_revision: variable predefinida con la revisión del sindarin en que esta corriendo, ejemplo:
      if (sindarin_revision != 0) say "Usando una versión beta de Sindarin"
    Las variables predefinidas no pueden ser modificas, 
    ante cualquier intento se emitirá un error

martes, 26 de agosto de 2008

Tutorial para muy novatos

Otro texto que escribí hace tiempo en relación a Sindarin, esta vez es un tutorial, muy simple:

Tutorial para muy novatos...(Revisado)

Vamos a aprender a hacer scripts, muy, muy sencillos...

click:

Este comando sirve para que se haga un click con el ráton en un punto de pantalla, para usarlo basta con poner "click" seguido de "left" (izquierdo en ingles) si quieres que use el botón izquierdo del ratón o "right" (derecho en ingles) y después tienes que poner el punto donde quieres que se haga "click". Por ejemplo:

click left [100,100]
click right [500,500]

Eso si, el punto tienes que escribirlo entre corchetes y separado por una coma [ , ] por que si no, no funcionara. Ya esta, eso es todo. Quizás tengas alguna duda de como averiguar el punto en el que quieres hacer click, para eso usa el botón capturar de la pestaña "location":


Si pulsas en "Capturar" y luego donde quieres que se haga click saldrán los números en donde pone X e Y. ¿Fácil verdad?

dclick:

Supongamos que queremos hacer un doble click con el ratón(pulsar dos veces muy rápido) para ello usamos este comando, que funciona igual que el anterior, escribes "dclick" seguido de "left" si quieres que el click se haga con el botón izquierdo o "right" si quieres que se haga con el derecho y luego pones el punto donde quieres que se haga, por ejemplo:

dclick left [25, 25]
dclick right [25, 25]

para ver el punto usa el botón capturar de la pestaña Location, como en click.

wait (esperar...)

¿Necesitas que el programa se pare un poco entre comando y comando? Para ello usa el comando "wait", escribes "wait" seguido de un numero de segundos que quieres que Sindarin se pare y ya esta por ejemplo:

wait 30

También puede hacer que se pare un numero de minutos:

wait 1 min
wait 15 min

pushkey (pulsar tecla)

Para que se pulse una tecla, para por ejemplo usar una macro, para ello escribimos "pushkey"(pulsar tecla en ingles) seguido de la tecla entre comillas simples 'tecla' por ejemplo:

pushkey 'a'
pushkey '1'
pushkey 'F1'
pushkey 'F12'

Aquí vemos como pulsamos la tecla "a", el "1", la tecla de función "F1" y la "F12".

Este comando es un poco largo de escribir, pero se puede escribir de varias formas, aunque hacen lo mismo:

pkey 'f5'
pkey 'b'
key 'C'
key '3'

Aquí hemos pulsado la tecla de función "F5", luego la "b", luego la "c" y por ultimo el "3", se puede escribir de cualquiera de esas formas y hará lo mismo.

drag (arrastrar)

¿Que pasa si queremos mover objetos de un sitio a otro?, tenemos el comando "drag", que sirve para mover objetos. Funciona escribiendo "drag" seguido de un numero, que sera el numero de objetos que vamos a mover, luego un punto donde estarán los objetos al principio y luego un punto donde queremos que deje los objetos, por ejemplo:

drag 1 [100,100] [25,25]
drag 12 objects [103,10] [205,25]
drag 25 [3,3] [2,2]

Primero movemos un objeto desde el punto [100,100] hasta el [25,25], luego movemos doce objetos desde el [103, 10] hasta el [205, 25], la palabra "objects" solo sirve para que sea mas fácilmente comprensible, no es realmente necesaria, y finalmente movemos veinticinco objetos desde [3,3] hasta [2,2].

Los puntos los podemos averiguar como hacíamos en el comando "click".

repeat (repetir)


Supongamos que queremos hacer una macro que pulse cuatro veces la tecla "F12" y haga una pausa de un segundo, por ejemplo:

pushkey 'F12'
wait 1
pushkey 'F12'
wait 1
pushkey 'F12'
wait 1
pushkey 'F12'
wait 1

Esto lo haría, pero... ¿no hay una forma de hacer que sindarin repita eso 4 veces sin que yo tenga que escribir cuatro veces lo mismo? Si para eso es el "repeat", funciona poniendo "repeat" seguido del numero de veces que quieres que se repita algo, luego el signo "{", luego los comandos que quieres que se repitan y terminas con otro símbolo "}", el ejemplo anterior nos quedaría así:

repeat 4
{
pushkey 'F12'
wait 1
}

Ya esta, no es muy complicado...

"Bufff pero eso del símbolo { y el símbolo } es un poco feo... ¿no?"

También puedes sustituir "{", "}" con "begin" y "end", así:

repeat 4
begin
 pushkey 'F12'
 wait 1
end

Cualquiera de las dos formas de escribirlo funcionara.

while (mientras)

"Vaya parece que solamente me ejecuta el script una sola vez, si escribo:"

pkey 'F1'
wait 1

"Solo me pulsa 'F1' una vez  y se detiene...¿Como puedo hacer que el script se repita muchas veces?"

La solución es usar "while" o "repeat" podrías poner un "repeat" muy grande:

repeat 40000
{
 pkey 'F1'
 wait 1
}

es decir, pones todo lo que quieres que se repita dentro de un "repeat" muy grande, en este caso se repetiría cuarenta mil veces, pero otra solución mucho mas elegante es:

while true
{
 pkey 'f1'
 wait 1
}

"While" sirve para repetir muchas veces unos comandos pero que en vez de repetirse un numero de veces se repite mientras se cumpla la condición escrita tras el. En el ejemplo como la condición de "while" es "true" (que significa que siempre es verdad), este código se repetiría para siempre, ¡¡Seria infinito!!


Teóricamente "while" no terminaría nunca, mientras que "repeat" se repite una serie de veces, pero en la practica es difícil que llegue a repetirse cuarenta mil veces, pero... nunca se sabe, además el "while" es mas elegante.

Pero... ¿como parar ese código infinito?

Bueno hay comandos que permiten detener el script:
  • "Break": Dentro del "while" haria que este terminara y por lo tanto el script.
  • "exit": En cualquier parte del script para totalmente el script.
En la ventana de Sindarin existen dos formas de parar cualquier código, pulsando el botón naranja de "Stop":

O manteniendo pulsado un tiempo (un segundo suele ser suficiente) la tecla "Pause/Break":

Esto ultimo solo funciona en Windows.

Bueno... Con esto ya podrías escribir tus propios scripts de forma sencilla, ahora si quieres profundizar y hacer cosas mas complicadas puede que te sean útiles estos dos post:


  1. Una explicación de todos los comandos de Sindarin.
  2. Algunas macros que me eran útiles en mis tiempos...

Sobre la ventana de Sindarin...

Sigo rescatando y reeditando viejos textos escritos sobre sindarin, esta vez sobre la ventana. Lamentablemente lo de capturar locations usando la ventana o capturar el color no funcionan correctamente en linux, pero los comandos para clickear y capturar colores si funcionan tanto en linux como en windows.


La ventana de Sindarin.

Vamos a explicar un poco como usar la ventana del Sindarin:


Las opciones de la pestaña "Control", rodeada por un recuadro verde, sirven para unir a Sindarin con una ejecución de Uo, los elementos de esta pestaña son:

  • La casilla "Modo nativo": esta casilla sirve para activar o desactivar el modo nativo, si desactivas esta opción, el Sindarin funcionara como el Autopilot, es decir que no te dejara usar el ordenador mientras macrea, aunque no lo parezca esto puede ser muy útil para ciertas scripts complicadas, porque hay algunos comandos que no funcionan muy bien en modo nativo. Por otra parte si el modo nativo esta funcionando, al capturar las localizaciones con el Sindarin, solo te cogeran puntos que estén dentro de la ventana de Uo y además el punto [0, 0] sera la esquina superior izquierda de la ventana de Ultima. Como dije antes si desactivas esta opción Sindarin tomara el control del ratón y el teclado, pero además al capturar una localización de pantalla sera con respecto a toda la ventana de windows y no solo a la de Ultima, de echo podrías hacer una script que hiciese cosas en windows en lugar de en Ultima y el punto [0, 0] seria la esquina superior izquierda de la pantalla de windows.
  • La lista desplegable: Suponiendo que Sindarin este funcionando en modo nativo y hubiese detectado la ventana de ultima, aquí sale el nombre de la ventana de ultima sobre la que Sindarin esta funcionando, en teoría detecta todas las que haya y en esa lista puedes elegir cual de todos los Ultimas quieres usar, en la practica yo nunca e usado mas de un Ultima, además el Cliente no te permite abrir mas de una, pero... hay esta la opción.
  • Botón "Buscar Uo": Si Sindarin no detecta la ventana de Ultima es probable que sea por que has abierto el Sindarin antes que la ventana de Ultima, bueno eso se arregla simplemente pulsando este botón, Sindarin intentara buscar la/s ventana/s de Ultima que estén activas y supondrá que la que quieres usar es la primera que encuentre.
Rodeado de un recuadro azul, están los botones típicos de Guardar, Cargar y también hay dos botones de Run(para que ponga a funcionar la macro) y un botón de Stop(para que pare la macro), que estará desactivado hasta que pulses Run. En principio un script(una macro) se puede parar por 4 motivos:

  • Pulsar el botón "Stop"
  • Mantener pulsada la tecla "Pause/Break" del teclado durante un pequeño tiempo, lamentablemente esto solo esta disponible en windows.
  • Por que se llega al final del script(esta diferencia es importante) , ya que al contrario que otros programas del mismo estilo al llegar al final del script
  • Encuentra el comando "exit", que termina la ejecución.
El cuadro de texto central es donde se introducen el código(algo evidente), justo debajo hay una etiqueta que en la imagen pone 3, ese es el numero de linea donde tienes el cursor del teclado. La parte gris de abajo donde pone "Print: Aquí salen los mensajes..." esa es lo que e llamado la consola de mensajes, esta parte es importante por que si nos equivocamos al escribir algún comando, el mensaje de aviso nos saldrá aquí. También saldrán los mensajes que pongas en el comando "print".

Y ahora una parte importantísima de la ventana que son las pestañas rodeadas de rojo, estas sirven para ayudarte a definir y inicializar variables, es decir que sirven para que pongas locations, macros, colores, etc... pero de una forma correcta y ayudan a averiguar por ejemplo que coordenadas tiene tal o tal punto, son las siguientes:

Pestaña "Location":


Aquí podemos ver varios componentes, los dos primeros son iguales para todos los tipos de variables, que son:
  • Botón con la flecha hacia abajo: Esto significa que la variable esta lista y quieres que se pegue en el código, al pulsarlo la variable "bajara" y se pegara al principio del código del script, si tiene algún valor este se pegara como valor inicial de la variable. No hay limite en el numero de variables que uses, puedes usar 0, 100 o 1000, lo único que limita el numero de variables es la cantidad de memoria que tenga tu ordenador.
  • Nombre: este sera el nombre que tendrá la variable, es decir si por ejemplo quieres poner un location que haga click sobre tu mochila pues lo normal seria que esa location se llamase "mochila" de forma que cuando mandes a sindarin a hacer un click con el botón izquierdo sobre la mochila pondrías:


    click left mochila


    Aunque el GUI te permitirá poner casi cualquier nombre, Sindarin solo acepta como nombres aquellos que tengan letras o números o subrayados "_", el resto de nombres dará error y los nombre nunca deben empezar por un numero, ejemplo de nombre correctos:

    • mochila_uno
    • _mochila
    • monton_de_regs_1
    ejemplos de nombre incorrectos:
    • 1000_nightshades
    • dirección de email
    • baúl!
    Por defecto las localizaciones se llaman "loc" seguidas de un numero, pero como ya e dicho lo normal es cambiar ese nombre por uno mas razonable.

    Por cierto existen unas variables especiales que las pone Sindarin desde un principio, ninguna otra variable puede llamarse así y tampoco pueden modificarse, de momento son estas:

    • sindarin_version
    • sindarin_revision
    • true
    • false
    Los campos "X" e "Y": aquí se ponen las coordenadas del punto al que haces referencia.

    Botón "Capturar": este botón es importante, sirve para saber que coordenadas tiene un punto de pantalla, es decir el punto de la location. Al pulsarlo se quedara esperando hasta que pinches en un punto de la pantalla con el botón izquierdo del ratón, e inmediatamente en la casilla
    "X" e "Y" aparecerán las coordenadas de ese punto, con lo que no tienes que calcular o copiarlas, simplemente inicializas el location haciendo click en un punto y listo.

    Este botón funciona de 2 formas distintas, si el Sindarin esta funcionando sobre una ventana de Ultima y el modo nativo esta activado, entonces el botón devuelve las coordenadas del punto respecto de la ventana de Ultima exclusivamente, es decir si haces click en la parte mas a la izquierda y arriba de Ultima saldría [0, 0], si hace click fuera de la ventana de Ultima las coordenadas que te salen
    son [-1, -1] que serian unas coordenadas incorrectas. El otro modo de funcionamiento es cuando Sindarin no a detectado la ventana de Ultima o cuando has desactivado la casilla de "Modo Nativo" con lo que "Capturar" te devolvería las coordenadas respecto de todo windows, esto es útil para hacer algunas scripts complejas, que por desgracia no te permitirían usar el ordenador mientras macreas, aunque te permitiría hacer scripts que hicieran cosas en windows, como intentar volver a arrancar el Ultima si se apaga solo( ^^ si tengo tiempo haré esta script, seria usando el comando "isnativemode" en un comando "if").

    Botón "Capturar loc y color": funciona igual que
    "Capturar", solo que además en la pestaña de "Color" aparecerá el color del punto en que has pinchado, es decir capturas la posición y el color de un punto de pantalla.

    Pestaña "Color":

    Sirve para inicializar colores, para por ejemplo saber si un punto de pantalla a cambiado de color o no, en la foto puedes ver:

    • Botón flecha hacia abajo: Funciona igual que en Location
    • Nombre: Igual que en Location
    • R, G, B: Es donde se ponen los valores del color que quieres inicializar, pueden ser de 0 a 255, por ejemplo si quieres el color rojo tendrías que poner: "255 0 0", aunque no es aconsejable que lo pongas a mano
    • Botón "Capturar": Funciona como el capturar de Location, pero en vez de capturar la posición de pantalla sobre la que pinches capturaras el color.
    • Botón "Captura desde loc": Sirve para capturar el color de un punto que hayas metido en Location, por ejemplo: Supón que quieres saber si el color de tu cara es o no tu color normal(para por ejemplo saber si has muerto o no) y siempre pones la hoja de personaje(paperdoll="ALT"+"P") en el mismo punto y un punto de tu cara esta en el [500, 500] pero quieres saber cual es el color de ese punto en concreto, pues pones 500 500 en las casillas "X" e "Y" de location, vas a Color y pulsas en este botón y ya tendrías el color del punto [500, 500] que por ejemplo seria el de tu cara normal o el de tu cara de muerto ( OoOoooOooooOOoOoo )

    Pestaña "Macrokey":

    Sirve para usar macros de Ultima fácilmente, es decir para que Sindarin pulse 'F1' o 'a', en la foto se puede ver:

    • Botón flecha hacia abajo: Funciona igual que en Location
    • Nombre: Igual que en Location
    • Tecla: Si pinchas aquí y pulsas una tecla aparecerá el nombre con que sindarin usa para pulsar esta tecla. En modo nativo solo funcionan las teclas de números, las de letras, las de función ('F1', 'F2', ..., 'F12') y la tecla 'Introduzca'( es el nombre que Java, y por lo tanto Sindarin, le da al Enter ), aunque si pulsas cualquier otra también saldrá su nombre, pero luego en Sindarin no funcionara, en modo normal funcionan todas, pero claro no podrás usar el teclado
    • Casillas "ALT", "CTRL" y "SHIFT": Si las marcas harás que Sindarin pulse también estas teclas junto con la que hayas escrito. Por desgracia tampoco funcionan en modo Nativo.

    Pestaña "Number":


    Sirve para declarar e inicializar variables numéricas, solo pueden usarse números enteros y positivos, podemos ver en la foto:

    • Botón flecha hacia abajo: Funciona igual que en Location
    • Nombre: Igual que en Location
    • Valor: Aquí puedes poner el numero que a de valer al principio, por ejemplo: Supon que quieres hacer una script para separar minerales, pues puedes usar un Number para controlar el numero de minerales que vas a separar:
    Location Minerales_apilados = [500, 500], minerales_no_apilados = [500, 510]
    Number cantidad_de_minerales = 100
    iodelay 100 msec  # Obliga a hacer 1 pausa tras cada comando de ratón o teclado de 100 milisegundos
    repeat cantidad_de_minerales
    drag 1 objects minerales_apilados from minerales_no_apilados
    # también se puede poner "drag 1 minerales_apilados minerales_no_apilados"
    

    Pestaña "String":


    Sirve para escribir o hacer que el pj diga algo, podemos ver:

    • Botón flecha hacia abajo: Funciona igual que en Location
    • Nombre: Igual que en Location
    • Valor: Escribes el texto que quieres que valga la variable
    Un ejemplo de uso de esto puede ser por ejemplo para hacer que tu pj diga si esta hambriento o no:

    String comando_del_hambre = ".hungry";
    say comando_del_hambre # evidentemente también se puede usar directamente la cadena
    say ".hungry"
    

    una utilidad de esto puede ser la de componer cadenas, por ejemplo:

    # Vamos a hacer que el pj se despida de un vendor y luego le pida el inventario
    String nombre_vendedor = "Marlon"
    say "bye"
    say nombre_vendedor + " buy"

    Nuestro personaje dirá "bye" y luego "marlon buy", lo cual puede ser muy útil

    Esto también se puede combinar con el comando "call" y los parametros ( $1, $2, ... ) podemos obtener una bonita script para comprar regs.

    Bueno y aunque no lo e explicado, en el menú comandos, solo hay un comando, es el comando "call" que sirve para que se ejecute un script dentro de otro, pero hay que decirle que script quieres que se ejecute, para ello hay que escribir la ruta y el nombre del script que quieres que se ejecute, como eso puede ser una pesadez en este menú te ayudara a elegir el script que quieres que se ejecute. Al pulsarlo te saldrá una ventana típica de abrir fichero, donde deberás seleccionar el fichero del script que quieres llamar y al aceptar, al final del código se pegar un comando "call" seguido del nombre del fichero entre ".

    Este comando es útil para hacer scripts complejas, por ejemplo podrías hacer un script que mirase si estas bajo de vida y si lo estas que hiciese doble-click sobre una poti de Health y luego llamarla desde una script para macrear Swordmanship con Osos invocados o tactics pegándote con otro Pj. "call" también puede escribirse simplemente con una "@"

    Y eso es mas o menos todo lo que tiene la ventana de Sindarin para ayudarte a hacer una script y a ejecutarla.

Sobre sindarin...



Sobre la ventana de Sindarin...
Tutorial para muy novatos
Explicación exhaustiva...



El siguiente post contiene parte de lo que escribí hace mucho tiempo sobre Sindarin en otra web, que tengo abandonada, así que lo voy a copiar aquí para que este accesible desde este Blog que si tengo "controlado", ademas he modificado muchas cosas del texto original que ya no son ciertas y he actualizado los enlaces:


  1. Aviso legal y normas generales de uso
  2. ¿Que es Sindarin?
  3. ¿Que es el modo Nativo?
  4. ¿Como instalo Sindarin?
  5. ¿Hay otra manera de usarlo?
  6. ¿Donde puedo descargarme el código del programa?
  7. ¿Como puedes tener tantas faltas de ortografía?
  8. Me encanta tu trabajo y quiero contratarte y darte un curro decente.
  9. Soy una chica atractiva y sexy y me gustaría tener un novio atractivo, inteligente y humilde como tu ¿Que debo hacer?

  1. Aviso legal y normas generales de uso
    • El uso del Sindarin implica la aceptación de estas normas, siendo conscientes de ellas o no.
    • No me hago responsable del mal uso que pueda hacerse del programa o cualquiera de sus módulos, clases o librerías.
    • El programa es de libre uso y no recibo ningún beneficio con el, por lo que no tengo ninguna obligación real, para
      con el o su mantenimiento.
    • El programa es de libre distribución, por lo que no esta permitido el beneficio económico por su uso o distribución.
    • Todas estas normas se aplicaran también a los diferentes módulos, clases, librerías desarrolladas o distribuidas con Sindarin.
    • Me reservo el derecho de hacer cambios en el código o funcionamiento del programa o cualquiera de sus partes en cualquier momento y sin previo aviso.
    • Actualización: El programa fue liberado bajo licencia GNU/GPL, por lo que queda acogido a sus condiciones.

  2. ¿Que es Sindarin?
  3. Sindarin es el nombre que le daban los elfos a la forma más común de su lenguaje según J.R.R. Tolkien y en Sindarin se escribía así:
    ¿Pero y esta aplicación que es? Esta aplicación es un asistente para Ultima Online del estilo de Autopilot, pero con la peculiaridad que los script que se pueden hacer son mucho mas sofisticados o tan sencillos como lo eran en Autopilot, con características propias de otros lenguajes más grandes, pero absolutamente opcionales, es decir la usan quien quiere y quien no, no las usa.

  4. ¿Que es el modo Nativo?
  5. Sindarin es un programa Java y en consecuencia multiplataforma, en teoría debería funcionar igual de bien en Windows, en Linux, en un Mac, en un Navegador o en tu ordenador local, pero Sindarin tiene un modo de funcionamiento que de momento solo funciona en Windows, es el modo Nativo Win32 es el modo que se pone por defecto. ¿Pero que es eso del modo nativo? bueno este modo es el que permite macrear sin ocupar el teclado y el ratón, es decir puedes usar el ordenador mientras macreas con el ultima y el Sindarin minimizados, pero esto tiene el problema que hace que el programa solo funcione así en Windows, lo cual no es muy buena actitud para Java. Este modo esta bien, pero es un modo de funcionamiento experimental, lo que implica que no tiene porque funcionar del todo bien, lo estoy probando, de echo existen ciertos comando de Sindarin(comandos avanzados) que no funcionan del todo bien.

  6. ¿Como instalo Sindarin?
  7. Tienes que tener Java instalado para ello puedes descargarlo de esta web http://www.java.com/es e instalarlo como un programa normal, es probable que ya este instalado en tu ordenador, porque es muy usado, simplemente si haz jugado en web de juegos es probable que lo hayas hecho en java. ¿Pero y Sindarin como lo instalo? En principio Sindarin no tiene un instalador, solo tendrías que como ya dije antes asegurarte que tienes Java y luego descargarte este fichero: http://sindarin.googlecode.com/files/Sindarin.jar Normalmente con hacer doble-click sobre el fichero de Sindarin.jar ya se abre la aplicación, pero sino es así, abre una ventana de shell o de dos, muévete hasta la carpeta y escribe: "java -jar Sindarin.jar"

  8. ¿Hay otra manera de usarlo?
  9. Si, Sindarin es un programa Java, pero también es un Applet Java, eso quiere decir que se puede ejecutar directamente desde una web, sin necesidad de descargarlo, siempre que tengas Java bien instalado y este el applet colgado de una web. Lamentablemente como nadie usaba esta opción he dejado de mantener el applet colgado, pero por poder se puede colgar.

  10. ¿Donde puedo descargarme el código del programa?

  1. ¿Como puedes tener tantas faltas de ortografía?
  2. Es simple no e usado el corrector ortográfico de ningún programa :P

  3. Me encanta tu trabajo y quiero contratarte y darte un curro decente.
  4. ¡Llegas tarde ya tengo curro! (aunque... ¬¬ podría oír lo que quieres decirme): Escribe a anphora@gmail.com

  5. Soy una chica atractiva y sexy y me gustaría tener un novio atractivo, inteligente y humilde como tu ¿Que debo hacer?
  6. Amiga, deja de buscar, yo soy tu hombre: Escribe a anphora@gmail.com