123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- #include "server/snuviscript/Snuvi.h"
- #include "Compiler.h"
- #include "data/HashMap.h"
- #undef MATH_H
- #include "common/NetworkPackets.h"
- #include "libraries/Math.h"
- #include "libraries/Time.h"
- #include "network/Server.h"
- #include "tokenizer/Tokenizer.h"
- #include "utils/StringBuffer.h"
- #include "vm/Script.h"
- static const char* unicode(int32 c) {
- static char buffer[5];
- int index = 0;
- if(c > 0xFFFF) {
- buffer[index++] = 0xF0 | ((c >> 18) & 0x07);
- buffer[index++] = 0x80 | ((c >> 12) & 0x3F);
- buffer[index++] = 0x80 | ((c >> 6) & 0x3F);
- buffer[index++] = 0x80 | (c & 0x3F);
- } else if(c > 0x7FF) {
- buffer[index++] = 0xE0 | ((c >> 12) & 0x0F);
- buffer[index++] = 0x80 | ((c >> 6) & 0x3F);
- buffer[index++] = 0x80 | (c & 0x3F);
- } else if(c > 0x7F) {
- buffer[index++] = 0xC0 | ((c >> 6) & 0x1F);
- buffer[index++] = 0x80 | (c & 0x3F);
- } else {
- buffer[index++] = c;
- }
- buffer[index++] = '\0';
- return buffer;
- }
- static void printString(Script* sc) {
- int length;
- Pointer p;
- if(!sPopPointer(sc, &p) || sGetPointerLength(sc, &p, &length)) {
- return;
- }
- OutPacket out(100);
- out.writeU8(static_cast<uint8>(ToClientPacket::CHAT));
- for(int i = 0; i < length; i++) {
- const void* data = sCheckAddress(sc, &p, sizeof(int));
- if(data != nullptr) {
- int c;
- memcpy(&c, data, sizeof(int));
- printf(unicode(c));
- out.writeU32(c);
- }
- p.offset += sizeof(int);
- }
- Server::send(out, PacketSendMode::RELIABLE);
- }
- static void printInt32(Script* sc) {
- int32 i;
- if(sPopInt32(sc, &i)) {
- printf("%d", i);
- }
- }
- static void wait(Script* sc) {
- sError(sc, "w");
- }
- static Snuvi::Event event = Snuvi::Event::NONE;
- static void getEvent(Script* sc) {
- sPushInt32(sc, static_cast<int>(event));
- }
- static void initPrinter() {
- Snuvi::initFunction("print", dtVoid(), printString);
- Snuvi::addArgument(dtConst(dtText()));
- Snuvi::addFunction();
- Snuvi::initFunction("print", dtVoid(), printInt32);
- Snuvi::addArgument(dtInt32());
- Snuvi::addFunction();
- }
- static int scriptId = 0;
- static HashMap<int, Script*> scripts;
- static Function function;
- void Snuvi::init() {
- gfsInit();
- gstsInit();
- lTimeRegister();
- lMathRegister();
- initPrinter();
- Snuvi::initFunction("wait", dtVoid(), wait);
- Snuvi::addFunction();
- Snuvi::initFunction("getEvent", dtInt32(), getEvent);
- Snuvi::addFunction();
- atexit([]() {
- gfsDelete();
- gstsDelete();
- Snuvi::termAll();
- });
- }
- void Snuvi::initFunction(const char* name, DataType returnType,
- ScriptFunction sf) {
- gfInit(&function, name, returnType, sf);
- }
- void Snuvi::addArgument(DataType type) {
- gfAddArgument(&function, type);
- }
- void Snuvi::addFunction() {
- gfsAdd(&function);
- }
- static void logError(const char* msg, int line) {
- puts(msg);
- printf("line: %d\n", line);
- }
- static bool runScript(Script* script) {
- sRun(script);
- if(script->error[0] == 'w' && script->error[1] == '\0') {
- script->error[0] = '\0';
- return false;
- } else if(script->error[0] != '\0') {
- logError(script->error, script->line);
- return true;
- }
- return script->readIndex >= script->code->length;
- }
- int Snuvi::start(const char* path) {
- StringBuffer<256> s("resources/scripts/");
- s.append(path).append(".snuvi");
- if(tTokenize(s)) {
- logError(tGetError(), tGetLine());
- return -1;
- }
- ByteCode* code = cCompile();
- if(code == nullptr) {
- logError(cGetError(), cGetLine());
- return -1;
- }
- Script* script = sInit(code);
- if(runScript(script)) {
- sDelete(script);
- return -1;
- }
- int id = scriptId++;
- scripts.tryEmplace(id, script);
- return id;
- }
- void Snuvi::termAll() {
- for(auto& entry : scripts) {
- sDelete(entry.value);
- }
- scripts.clear();
- }
- void Snuvi::callEvent(Event e) {
- event = e;
- for(auto& entry : scripts) {
- if(runScript(entry.value)) {
- sDelete(entry.value);
- scripts.remove(entry.getKey());
- }
- }
- }
- static int32 readChar(int& index, const char* s) {
- if(s[index] == '\0') {
- return '\0';
- }
- return s[index++];
- }
- Pointer Snuvi::toString(Script* sc, const char* s) {
- List<int> data;
- int index = 0;
- while(s[index] != '\0') {
- int32 c = readChar(index, s);
- if((c & 0xE0) == 0xC0) {
- c = ((c & 0x1F) << 6) | (readChar(index, s) & 0x3F);
- } else if((c & 0xF0) == 0xE0) {
- c = ((c & 0xF) << 12) | ((readChar(index, s) & 0x3F) << 6);
- c |= readChar(index, s) & 0x3F;
- } else if((c & 0xF8) == 0xF0) {
- c = ((c & 0x7) << 18) | ((readChar(index, s) & 0x3F) << 12);
- c |= (readChar(index, s) & 0x3F) << 6;
- c |= readChar(index, s) & 0x3F;
- }
- data.add(c);
- }
- Pointer p;
- p.offset = 0;
- p.array = asAllocate(&sc->arrays, sizeof(int32), data.getLength());
- SnuviArray* array = asGet(&sc->arrays, p.array);
- if(array == nullptr) {
- sError(sc, "cannot allocate string memory");
- p.offset = -1;
- p.array = -1;
- } else {
- memcpy(array->data, data.begin(), sizeof(int32) * data.getLength());
- }
- return p;
- }
|