Bool CreateAccount(char *name,char *password,int type,int *account_id) { char buf[ENCRYPT_LEN+1]; account_node *a; if (GetAccountByName(name) != NULL) return False; a = (account_node *)AllocateMemory(MALLOC_ID_ACCOUNT,sizeof(account_node)); a->account_id = next_account_id++; a->name = (char *)AllocateMemory(MALLOC_ID_ACCOUNT,strlen(name)+1); strcpy(a->name,name); MDString(password,(unsigned char *) buf); buf[ENCRYPT_LEN] = 0; a->password = (char *)AllocateMemory(MALLOC_ID_ACCOUNT,strlen(buf)+1); strcpy(a->password,buf); a->type = type; a->last_login_time = 0; a->suspend_time = 0; a->credits = 100*ConfigInt(CREDIT_INIT); InsertAccount(a); *account_id = a->account_id; return True; }
int CreateAccountSecurePassword(char *name,char *password,int type) { char buf[100],*ptr; int index; account_node *a; unsigned int ch; index = 0; ptr = password; while (sscanf(ptr,"%02x",&ch) == 1) { buf[index++] = ch; ptr += 2; } buf[index] = 0; a = (account_node *)AllocateMemory(MALLOC_ID_ACCOUNT,sizeof(account_node)); a->account_id = next_account_id++; a->name = (char *)AllocateMemory(MALLOC_ID_ACCOUNT,strlen(name)+1); strcpy(a->name,name); a->password = (char *)AllocateMemory(MALLOC_ID_ACCOUNT,strlen(buf)+1); strcpy(a->password,buf); a->type = type; a->last_login_time = 0; a->suspend_time = 0; a->credits = 100*ConfigInt(CREDIT_INIT); InsertAccount(a); return a->account_id; }
/* InitSession * * This allocates an array of session nodes for max people that can be connected, * even if they're overflow and we're gonna hang them up. This array is never * freed. */ void InitSession() { epoch = 1; transmitted_bytes = 0; sessions = (session_node *) AllocateMemory(MALLOC_ID_SESSION_MODES,ConfigInt(SESSION_MAX_CONNECT)*sizeof(session_node)); num_sessions = 0; if (sizeof(admin_data) > SESSION_STATE_BYTES) FatalError("sizeof(admin_data) must be <= SESSION_STATE_BYTES"); if (sizeof(game_data) > SESSION_STATE_BYTES) FatalError("sizeof(game_data) must be <= SESSION_STATE_BYTES"); if (sizeof(trysync_data) > SESSION_STATE_BYTES) FatalError("sizeof(trysync_data) must be <= SESSION_STATE_BYTES"); if (sizeof(synched_data) > SESSION_STATE_BYTES) FatalError("sizeof(synched_data) must be <= SESSION_STATE_BYTES"); if (sizeof(resync_data) > SESSION_STATE_BYTES) FatalError("sizeof(resync_data) must be <= SESSION_STATE_BYTES"); InitializeCriticalSection(&csSessions); }
void GameStartUser(session_node *s,user_node *u) { parm_node p; val_type session_id_const; s->game->object_id = u->object_id; session_id_const.v.tag = TAG_SESSION; session_id_const.v.data = s->session_id; p.type = CONSTANT; p.value = session_id_const.int_val; p.name_id = SESSION_ID_PARM; SendTopLevelBlakodMessage(s->game->object_id,USER_ENTER_GAME_MSG,1,&p); // Log of characters, accounts, ips val_type name_val; resource_node *r; name_val.int_val = SendTopLevelBlakodMessage(s->game->object_id,USER_NAME_MSG,0,NULL); r = GetResourceByID(name_val.v.data); if (r && r->resource_val) MySQLRecordPlayerLogin(s->account->name,r->resource_val,s->conn.name); SetSessionTimer(s,ConfigInt(CREDIT_DRAIN_TIME)); }
void GameProcessSessionTimer(session_node *s) { if (s->game->object_id == INVALID_OBJECT) { /* timed out before credits drain means took too long picking character */ HangupSession(s); return; } /* they're in the game. First thing to check is if we haven't gotten any message in a while, even ping. If so, they are so lagged they should be hung up. */ /* dprintf("%u %u %u\n",GetTime(),s->game->game_last_message_time,ConfigInt(INACTIVE_GAME)); */ if (GetTime() - s->game->game_last_message_time > ConfigInt(INACTIVE_GAME)) { lprintf("GameProcessSessionTimer logging out ACCOUNT %i (%s) which hasn't been heard from.\n", s->account->account_id, s->account->name); HangupSession(s); return; } SetSessionTimer(s,ConfigInt(CREDIT_DRAIN_TIME)); s->account->credits -= ConfigInt(CREDIT_DRAIN_AMOUNT); if (s->game->game_state != GAME_NORMAL) return; #if 0 /* warn them when they are low */ if ((s->account->credits <= 100*ConfigInt(CREDIT_WARN1)) && (s->account->credits + ConfigInt(CREDIT_DRAIN_AMOUNT) > 100*ConfigInt(CREDIT_WARN1)) || (s->account->credits == 100*ConfigInt(CREDIT_WARN2)) && (s->account->credits + ConfigInt(CREDIT_DRAIN_AMOUNT) > 100*ConfigInt(CREDIT_WARN2))) GameWarnLowCredits(s); if (s->account->credits == 0) { /* send them an out-of-credits message */ GameClientExit(s); SetSessionState(s,STATE_SYNCHED); } #endif }
session_node *AllocateSession(void) { int i; for (i=0;i<num_sessions;i++) { if (sessions[i].connected == False) break; } if (i == num_sessions) { /* if no emptied low number sessions and using every session, can't use them */ if (num_sessions == ConfigInt(SESSION_MAX_CONNECT)) return NULL; num_sessions++; } /* we're gonna hang 'em up once synched if too many people on*/ sessions[i].active = i < ConfigInt(SESSION_MAX_ACTIVE); sessions[i].session_id = i; sessions[i].blak_client = False; sessions[i].login_verified = False; sessions[i].hangup = False; sessions[i].account = NULL; sessions[i].exiting_state = False; sessions[i].receive_list = NULL; sessions[i].receive_index = 0; sessions[i].send_list = NULL; sessions[i].version_major = 0; sessions[i].version_minor = 0; sessions[i].seeds_hacked = False; sessions[i].secure_token = 0; sessions[i].sliding_token = NULL; return &sessions[i]; }
void GameInit(session_node *s) { s->game = (game_data *)s->session_state_data; s->game->object_id = INVALID_OBJECT; SetSessionTimer(s,60*ConfigInt(INACTIVE_SELECTCHAR)); s->game->game_state = GAME_NORMAL; s->game->game_last_message_time = GetTime(); GameSendSystemEnter(s); }
account_node * AccountLoginByName(char *name) { account_node *a; if (0 == stricmp(name,ConfigStr(GUEST_ACCOUNT))) { if (GetUsedGuestAccounts() >= ConfigInt(GUEST_MAX)) return NULL; a = accounts; while (a != NULL) { if (a->type == ACCOUNT_GUEST) { if (GetSessionByAccount(a) == NULL) { /* no one using this particular guest account, so we will */ /* give guests credits every time they login */ /* a->credits = 100*ConfigInt(GUEST_CREDITS); */ return a; } } a = a->next; } } else { a = accounts; while (a != NULL) { if (!stricmp(a->name,name)) { /* give administrators credits every time they login */ /* if (a->type == ACCOUNT_ADMIN) a->credits = 100*ConfigInt(CREDIT_ADMIN); */ return a; } a = a->next; } } return NULL; }
void GameStartUser(session_node *s,user_node *u) { parm_node p; val_type session_id_const; s->game->object_id = u->object_id; session_id_const.v.tag = TAG_SESSION; session_id_const.v.data = s->session_id; p.type = CONSTANT; p.value = session_id_const.int_val; p.name_id = SESSION_ID_PARM; SendTopLevelBlakodMessage(s->game->object_id,USER_ENTER_GAME_MSG,1,&p); SetSessionTimer(s,ConfigInt(CREDIT_DRAIN_TIME)); }
void GameDMCommand(session_node *s,int type,char *str) { char buf[LEN_MAX_CLIENT_MSG + 200]; int acctype; acctype = ACCOUNT_NORMAL; if (s && s->account) acctype = s->account->type; // dprintf("DM command %i by session %i account %i acctype %i; string is \"%s\".\n", // type, s->session_id, s->account->account_id, acctype, str); switch (type) { case DM_CMD_GO_ROOM : if (0 != atoi(str)) { //ASSERT(0 != ACCOUNT_ADMIN); //ASSERT(0 != ACCOUNT_DM); if (ConfigInt(RIGHTS_GOROOMBYNUM) == 0) { dprintf("DM Command GOROOM (by number) disabled."); break; } if (ConfigInt(RIGHTS_GOROOMBYNUM) == ACCOUNT_ADMIN && acctype == ACCOUNT_DM) { dprintf("DM Command GOROOM (by number) disabled for DMs; must be Admin."); break; } } if (ConfigInt(RIGHTS_GOROOM) == 0) { dprintf("DM Command GOROOM disabled."); break; } if (ConfigInt(RIGHTS_GOROOM) == ACCOUNT_ADMIN && acctype == ACCOUNT_DM) { dprintf("DM Command GOROOM disabled for DMs; must be Admin."); break; } sprintf(buf,"send object %i teleportto rid int %s",s->game->object_id,str); SendSessionAdminText(s->session_id,"~B> %s\n",buf); /* echo it to 'em */ TryAdminCommand(s->session_id,buf); break; case DM_CMD_GO_PLAYER : if (ConfigInt(RIGHTS_GOPLAYER) == 0) break; if (ConfigInt(RIGHTS_GOPLAYER) == ACCOUNT_ADMIN && acctype == ACCOUNT_DM) break; sprintf(buf,"send object %i admingotoobject what object %s",s->game->object_id,str); SendSessionAdminText(s->session_id,"~B> %s\n",buf); /* echo it to 'em */ TryAdminCommand(s->session_id,buf); break; case DM_CMD_GET_PLAYER : if (ConfigInt(RIGHTS_GETPLAYER) == 0) break; if (ConfigInt(RIGHTS_GETPLAYER) == ACCOUNT_ADMIN && acctype == ACCOUNT_DM) break; sprintf(buf,"send object %s admingotoobject what object %i",str,s->game->object_id); SendSessionAdminText(s->session_id,"~B> %s\n",buf); /* echo it to 'em */ TryAdminCommand(s->session_id,buf); break; default : eprintf("GameDMCommand got invalid DM command type %i\n",type); break; } }
void InitSMTP(void) { if (ConfigBool(EMAIL_LISTEN) == True) AcceptSMTPSocketConnections(ConfigInt(EMAIL_PORT)); }
/* returns either RETURN_PROPAGATE or RETURN_NO_PROPAGATE. If no propagate, * then the return value in ret_val is good. */ int InterpretAtMessage(int object_id,class_node* c,message_node* m, int num_sent_parms, parm_node sent_parms[],val_type *ret_val) { opcode_type opcode; char opcode_char; char num_locals,num_parms; local_var_type local_vars; int parm_id; val_type parm_init_value; int i,j; char *inst_start; Bool found_parm; num_locals = get_byte(); num_parms = get_byte(); local_vars.num_locals = num_locals+num_parms; if (local_vars.num_locals > MAX_LOCALS) { dprintf("InterpretAtMessage found too many locals and parms for OBJECT %i CLASS %s MESSAGE %s (%s) aborting and returning NIL\n", object_id, c? c->class_name : "(unknown)", m? GetNameByID(m->message_id) : "(unknown)", BlakodDebugInfo()); (*ret_val).int_val = NIL; return RETURN_NO_PROPAGATE; } if (ConfigBool(DEBUG_INITLOCALS)) { parm_init_value.v.tag = TAG_INVALID; parm_init_value.v.data = 1; for (i = 0; i < local_vars.num_locals; i++) { local_vars.locals[i] = parm_init_value; } } /* both table and call parms are sorted */ j = 0; for (i=0;i<num_parms;i++) { parm_id = get_int(); /* match this with parameters */ parm_init_value.int_val = get_int(); /* look if we have a value for this parm */ found_parm = False; j = 0; /* don't assume sorted for now */ while (j < num_sent_parms) { if (sent_parms[j].name_id == parm_id) { /* assuming no RetrieveValue needed here, since InterpretCall does that for us */ local_vars.locals[i].int_val = sent_parms[j].value; found_parm = True; j++; break; } j++; } if (!found_parm) local_vars.locals[i].int_val = parm_init_value.int_val; } for(;;) /* returns when gets a blakod return */ { num_interpreted++; /* infinite loop check */ if (num_interpreted > ConfigInt(BLAKOD_MAX_STATEMENTS)) { bprintf("InterpretAtMessage interpreted too many instructions--infinite loop?\n"); dprintf("Infinite loop at depth %i\n", message_depth); dprintf(" OBJECT %i CLASS %s MESSAGE %s (%s) aborting and returning NIL\n", object_id, c? c->class_name : "(unknown)", m? GetNameByID(m->message_id) : "(unknown)", BlakodDebugInfo()); dprintf(" Local variables:\n"); for (i=0;i<local_vars.num_locals;i++) { dprintf(" %3i : %s %5i\n", i, GetTagName(local_vars.locals[i]), local_vars.locals[i].v.data); } (*ret_val).int_val = NIL; return RETURN_NO_PROPAGATE; } opcode_char = get_byte(); //memcpy(&opcode,&opcode_char,1); { char *ch=(char*)&opcode; *ch = opcode_char ; } /* use continues instead of breaks here since there is nothing after the switch, for efficiency */ switch (opcode.command) { case UNARY_ASSIGN : InterpretUnaryAssign(object_id,&local_vars,opcode); continue; case BINARY_ASSIGN : InterpretBinaryAssign(object_id,&local_vars,opcode); continue; case GOTO : inst_start = bkod - 1; /* we've read one byte of instruction so far */ InterpretGoto(object_id,&local_vars,opcode,inst_start); continue; case CALL : InterpretCall(object_id,&local_vars,opcode); continue; case RETURN : if (opcode.dest == PROPAGATE) return RETURN_PROPAGATE; else { int data; data = get_int(); *ret_val = RetrieveValue(object_id,&local_vars,opcode.source1,data); return RETURN_NO_PROPAGATE; } /* can't get here */ continue; default : bprintf("InterpretAtMessage found INVALID OPCODE command %i. die.\n", opcode.command); FlushDefaultChannels(); continue; } } }
/* returns the return value of the blakod */ int SendTopLevelBlakodMessage(int object_id,int message_id,int num_parms,parm_node parms[]) { int ret_val = 0; UINT64 start_time = 0; int interp_time = 0; int posts = 0; int accumulated_num_interpreted = 0; if (message_depth != 0) { eprintf("SendTopLevelBlakodMessage called with message_depth %i\n",message_depth); } kod_stat.debugging = ConfigBool(DEBUG_UNINITIALIZED); start_time = GetMilliCount(); kod_stat.num_top_level_messages++; trace_session_id = INVALID_ID; num_interpreted = 0; ret_val = SendBlakodMessage(object_id,message_id,num_parms,parms); while (post_q.next != post_q.last) { posts++; accumulated_num_interpreted += num_interpreted; num_interpreted = 0; if (accumulated_num_interpreted > 10*ConfigInt(BLAKOD_MAX_STATEMENTS)) { bprintf("SendTopLevelBlakodMessage too many instructions in posted followups\n"); dprintf("SendTopLevelBlakodMessage too many instructions in posted followups\n"); dprintf(" OBJECT %i CLASS %s MESSAGE %s (%i) some followups are being aborted\n", object_id, GetClassByID(GetObjectByID(object_id)->class_id)->class_name, GetNameByID(message_id), message_id); break; } /* posted messages' return value is ignored */ SendBlakodMessage(post_q.data[post_q.last].object_id,post_q.data[post_q.last].message_id, post_q.data[post_q.last].num_parms,post_q.data[post_q.last].parms); post_q.last = (post_q.last + 1) % MAX_POST_QUEUE; } interp_time = (int)(GetMilliCount() - start_time); kod_stat.interpreting_time += interp_time; if (interp_time > kod_stat.interpreting_time_highest) { kod_stat.interpreting_time_highest = interp_time; kod_stat.interpreting_time_message_id = message_id; kod_stat.interpreting_time_object_id = object_id; kod_stat.interpreting_time_posts = posts; } if (interp_time > 1000) { kod_stat.interpreting_time_over_second++; kod_stat.interpreting_time_message_id = message_id; kod_stat.interpreting_time_object_id = object_id; kod_stat.interpreting_time_posts = posts; } if (num_interpreted > kod_stat.num_interpreted_highest) kod_stat.num_interpreted_highest = num_interpreted; kod_stat.num_interpreted += num_interpreted; if (kod_stat.num_interpreted > 1000000000L) { kod_stat.num_interpreted -= 1000000000L; kod_stat.billions_interpreted++; } if (message_depth != 0) { eprintf("SendTopLevelBlakodMessage returning with message_depth %i\n",message_depth); } return ret_val; }
void AsyncSocketStart(void) { AcceptSocketConnections(ConfigInt(SOCKET_PORT),SOCKET_PORT); AcceptSocketConnections(ConfigInt(SOCKET_MAINTENANCE_PORT),SOCKET_MAINTENANCE_PORT); }