Share Pastebin
Guest
Public paste!

Thyth

By: a guest | Feb 9th, 2010 | Syntax: C++ | Size: 3.43 KB | Hits: 23 | Expires: Never
Copy text to clipboard
  1. /*
  2.  * rubyIntersect.cpp
  3.  *
  4.  *  Created on: Jan 25, 2009
  5.  *      Author: Thyth
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <windows.h>
  11.  
  12. #include "ruby.h"
  13. #include "processChecker.h"
  14. #include "hexStream.h"
  15.  
  16. namespace Ruby
  17. {
  18.         VALUE rb_tsEval(VALUE self, VALUE exec);
  19.         VALUE str2val(const char *s);
  20.         char* val2str(VALUE v);
  21.         void init();
  22.         VALUE out(VALUE self, VALUE str);
  23.  
  24.         VALUE out(VALUE self, VALUE str)
  25.         {
  26.                 char* output = hex_encode(val2str(str));
  27.                 if (self == rb_stdout)
  28.                         printf("output: %s\n", output);
  29.                 else
  30.                         printf("error: %s\n", output);
  31.                 fflush(stdout);
  32.                 free(output);
  33.  
  34.                 return rb_fix_new(RSTRING(str)->len * sizeof(RSTRING(str)->ptr[0]));
  35.         }
  36.  
  37.         // Print to ruby AND t2 consoles
  38.         void error(const char *fmt, ...)
  39.         {
  40.                 va_list argptr;
  41.                 va_start(argptr, fmt);
  42.  
  43.                 char* errorBuffer = (char*)calloc(16384, sizeof(char));
  44.                 sprintf(errorBuffer, fmt, argptr);
  45.                 va_end(argptr);
  46.  
  47.                 char* output = hex_encode(errorBuffer);
  48.                 printf("error: %s\n", output);
  49.                 fflush(stdout);
  50.  
  51.                 free(output);
  52.                 free(errorBuffer);
  53.         }
  54.  
  55.  
  56.         // Display exception info...
  57.         void exception()
  58.         {
  59.                 VALUE mesg = rb_obj_as_string(rb_gv_get("$!"));
  60.                 error("%s", val2str(mesg));
  61.         }
  62.  
  63.         // Convert VALUE to char*
  64.         char* val2str(VALUE v)
  65.         {
  66.                 if (NIL_P(v))
  67.                         return "nil";
  68.  
  69.                 return STR2CSTR(rb_funcall(v, rb_intern("to_s"), 0));
  70.         }
  71.  
  72.         // Convert char* to VALUE
  73.         VALUE str2val(const char *s)
  74.         {
  75.                 if (s == NULL)
  76.                         return Qnil;
  77.  
  78.                 return rb_str_new2(s);
  79.         }
  80.  
  81.         // Let's evaluate some t-script from ruby!
  82.         VALUE rb_tsEval(VALUE self, VALUE exec)
  83.         {
  84.                 char* output = hex_encode(val2str(exec));
  85.                 printf("console: %s\n", output);
  86.                 fflush(stdout);
  87.                 free(output);
  88.                 return str2val("nil");
  89.         }
  90.  
  91.         VALUE rb_exit(VALUE self, VALUE exec)
  92.         {
  93.                 exit(0);
  94.         }
  95.  
  96.         void doEval(char* string)
  97.         {
  98.                 int err = 0;
  99.                 rb_eval_string_protect(string, &err);
  100.  
  101.                 if (err)
  102.                 {
  103.                         error("Runtime error (%d)", err);
  104.                         //exception(); // seems to be causing crashes
  105.                 }
  106.         }
  107.  
  108.         void init()
  109.         {
  110.                 rb_define_singleton_method(rb_stdout, "write", RUBY_METHOD_FUNC(out), 1);
  111.                 rb_define_singleton_method(rb_stderr, "write", RUBY_METHOD_FUNC(out), 1);
  112.                 rb_define_global_function("tsEval", RUBY_METHOD_FUNC(rb_tsEval), 1);
  113.                 rb_define_global_function("exit", RUBY_METHOD_FUNC(rb_exit), 0);
  114.         }
  115. }
  116.  
  117. int parent_pid;
  118.  
  119. DWORD WINAPI gameCrashDetectThread(void* arg)
  120. {
  121.         while (1)
  122.         {
  123.                 if (!processActive(parent_pid))
  124.                 {
  125.                         // parent process has been terminated. terminate interpreter
  126.                         //abort();
  127.                         ExitProcess(0);
  128.                 }
  129.  
  130.                 // sleep for 5 seconds before checking again
  131.                 Sleep(5000);
  132.         }
  133. }
  134.  
  135. int main(int argc, char *argv[])
  136. {
  137.         // start the process watch thread to see if the parent game process has terminated
  138.         if (argc != 2)
  139.         {
  140.                 MessageBoxA(NULL,
  141.                                 "Ruby Interpreter parent process connection failed.",
  142.                                 "Fatal Error",
  143.                                 MB_ICONERROR | MB_OK);
  144.                 exit(1);
  145.         }
  146.         parent_pid = atoi(argv[1]);
  147.  
  148.         // spawn a thread
  149.         CreateThread(NULL, 0, gameCrashDetectThread, NULL, 0, NULL);
  150.  
  151.         // initialize the embedded ruby interpreter
  152.         ruby_init();
  153.         ruby_init_loadpath();
  154.         ruby_script("embedded");
  155.         Ruby::init();
  156.  
  157.         // being processing standard in and out
  158.         char* buffer = (char*)malloc(8388608);
  159.         while (true)
  160.         {
  161.                 fgets(buffer, 8388608, stdin);
  162.                 char* decoded = hex_decode(buffer);
  163.                 //printf("Decoded: %s\n", decoded);
  164.                 Ruby::doEval(decoded);
  165.                 free(decoded);
  166.                 printf("done: \n");
  167.                 fflush(stdout);
  168.         }
  169.  
  170.         return 0;
  171. }