long CALLBACK InterfaceAdminInputProc(HWND hwnd, UINT message, UINT wParam, LONG lParam) { char buf[200]; switch (message) { case WM_CHAR : if (wParam == '\r') { if (InMainLoop() && !GetQuit()) { /* make sure we've started already, so that session id is valid */ Edit_SetSel(hwnd,0,-1); Edit_GetText(hwnd,buf,sizeof buf); cprintf(console_session_id,"%s\n",buf); EnterServerLock(); TryAdminCommand(console_session_id,buf); LeaveServerLock(); } return 0; } if (wParam == '\t') { SetFocus(GetDlgItem(HWND_ADMIN,IDC_ADMIN_RESPONSE)); return 0; } } return CallWindowProc(lpfnDefAdminInputProc,hwnd,message,wParam,lParam); }
void* InterfaceMainLoop(void* arg) { char *line = (char*) malloc(200); size_t size; //char buf[200]; while (strcmp(line,"quit") != 0) { printf("blakadm> "); if (getline(&line, &size, stdin) != -1) { EnterServerLock(); // TODO: in windows this uses a set char array of size 200, no bounds checking // is being done here yet //TryAdminCommand(console_session_id,buf); TryAdminCommand(console_session_id,line); LeaveServerLock(); } } free(line); MessagePost(main_thread_id,WM_QUIT,0,0); }
void DeleteAccountFromBuffer(char *buf) { char *line; char *version,*name; account_node *a; version = name = NULL; line = strtok(buf,"\r\n"); while (line != NULL) { if (ConfigBool(DEBUG_SMTP)) { dprintf(": %i %s\n",strlen(line),line); Sleep(500); } if (strcmp(line,"VERSION:") == 0) version = strtok(NULL,"\r\n"); if (strcmp(line,"NAME:") == 0) name = strtok(NULL,"\r\n"); line = strtok(NULL,"\r\n"); } if (version == NULL) { eprintf("DeleteAccountFromBuffer got no version\n"); return; } if (strcmp(version,"1") != 0) { eprintf("DeleteAccountFromBuffer got version != 1 (%s)\n",version); return; } if (name == NULL) { eprintf("DeleteAccountFromBuffer got email w/o name\n"); return; } EnterServerLock(); a = GetAccountByName(name); if (a == NULL) eprintf("DeleteAccountFromBuffer got email w/name that's not a valid account %s\n",name); else PostThreadMessage(main_thread_id,WM_BLAK_MAIN_DELETE_ACCOUNT,0,a->account_id); LeaveServerLock(); }
void InterfaceReloadSystem() { EnterServerLock(); lprintf("InterfaceReloadSystem reloading system\n"); PauseTimers(); SendBlakodBeginSystemEvent(SYSEVENT_RELOAD_SYSTEM); GarbageCollect(); SaveAll(); ResetAdminConstants(); ResetUser(); ResetString(); ResetRoomData(); ResetLoadMotd(); ResetLoadBof(); ResetDLlist(); ResetNameID(); ResetResource(); ResetTimer(); ResetList(); ResetObject(); ResetMessage(); ResetClass(); LoadMotd(); LoadBof(); LoadRsc(); LoadKodbase(); UpdateSecurityRedbook(); LoadAdminConstants(); /* can't reload accounts because sessions have pointers to accounts */ if (!LoadAllButAccount()) eprintf("InterfaceReloadSystem couldn't load game. You are dead.\n"); AllocateParseClientListNodes(); /* it needs a list to send to users */ AddBuiltInDLlist(); SendBlakodEndSystemEvent(SYSEVENT_RELOAD_SYSTEM); UnpauseTimers(); LeaveServerLock(); }
BOOL CALLBACK InterfaceDialogMotd(HWND hwnd,UINT message,UINT wParam,LONG lParam) { char s[2000]; switch (message) { case WM_INITDIALOG : CenterWindow(hwnd,NULL); Edit_LimitText(GetDlgItem(hwnd,IDC_MOTD),sizeof(s)-1); EnterServerLock(); Edit_SetText(GetDlgItem(hwnd,IDC_MOTD),GetMotd()); LeaveServerLock(); return TRUE; case WM_COMMAND : switch (wParam) { case IDOK : Edit_GetText(GetDlgItem(hwnd,IDC_MOTD),s,sizeof(s)-1); EnterServerLock(); SetMotd(s); LeaveServerLock(); EndDialog(hwnd,0); return TRUE; case IDCANCEL : EndDialog(hwnd,0); return TRUE; } } return FALSE; }
void AsyncNameLookup(HANDLE hLookup,int error) { if (error != 0) { /* eprintf("AsyncSocketNameLookup got error %i\n",error); */ return; } name_lookup_handle = hLookup; EnterServerLock(); ForEachSession(AsyncEachSessionNameLookup); LeaveServerLock(); }
void InterfaceSave() { EnterServerLock(); lprintf("InterfaceSave saving\n"); PauseTimers(); SendBlakodBeginSystemEvent(SYSEVENT_SAVE); /* ResetRoomData(); */ GarbageCollect(); SaveAll(); AllocateParseClientListNodes(); /* it needs a list to send to users */ SendBlakodEndSystemEvent(SYSEVENT_SAVE); UnpauseTimers(); LeaveServerLock(); }
void InterfaceAddList(int session_id) { session_node *s; LV_ITEM lvi; int index; EnterServerLock(); s = GetSessionByID(session_id); if (s == NULL) { LeaveServerLock(); return; } index = ListView_GetItemCount(hwndLV); /* Initialize LV_ITEM members that are common to all items. */ lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; lvi.state = 0; lvi.stateMask = 0; lvi.pszText = " ?"; lvi.iImage = -1; lvi.iItem = index; lvi.iSubItem = 0; lvi.lParam = session_id; ListView_InsertItem(hwndLV,&lvi); if (s->account == NULL) { /* need braces around this macro to use in an if/else */ ListView_SetItemText(hwndLV,index,1,""); } else ListView_SetItemText(hwndLV,index,1,s->account->name); ListView_SetItemText(hwndLV,index,2,ShortTimeStr(s->connected_time)); ListView_SetItemText(hwndLV,index,3,GetStateName(s)); ListView_SetItemText(hwndLV,index,4,s->conn.name); LeaveServerLock(); }
Bool ExistInternetMailName(char *s) { #ifdef SMTP_TEST return True; #else val_type ret_val; return (strcmp(s,ConfigStr(EMAIL_ACCOUNT_CREATE_NAME)) == 0) || (strcmp(s,ConfigStr(EMAIL_ACCOUNT_DELETE_NAME)) == 0); /* only account creation right now */ EnterServerLock(); ret_val.int_val = GetInternetMailObject(s); LeaveServerLock(); return (ret_val.v.tag == TAG_OBJECT); #endif }
void InterfaceUpdateList(int session_id) { session_node *s; char buf[20]; LV_FINDINFO lvf; int index; EnterServerLock(); s = GetSessionByID(session_id); if (s == NULL) { LeaveServerLock(); return; } lvf.flags = LVFI_PARAM; lvf.lParam = session_id; index = ListView_FindItem(hwndLV,-1,&lvf); if (index >= 0) { if (s->account == NULL) { ListView_SetItemText(hwndLV,index,0," ?"); ListView_SetItemText(hwndLV,index,1,""); } else { sprintf(buf,"%3i",s->account->account_id); ListView_SetItemText(hwndLV,index,0,buf); ListView_SetItemText(hwndLV,index,1,s->account->name); } ListView_SetItemText(hwndLV,index,2,ShortTimeStr(s->connected_time)); ListView_SetItemText(hwndLV,index,3,GetStateName(s)); ListView_SetItemText(hwndLV,index,4,s->conn.name); } LeaveServerLock(); }
void ProcessMessageDataDone(smtp_node *smtp) { string_list *sl; val_type object_val; int string_id; CreateAccountFromSMTPMail(smtp); return; EnterServerLock(); /* take smtp->data and make it into a string in the game */ string_id = MakeStringFromSMTPMail(smtp); /* now, send it to each person who it was sent to */ sl = smtp->forward_path; while (sl != NULL) { object_val.int_val = GetInternetMailObject(sl->str); if (object_val.v.tag != TAG_OBJECT) eprintf("ProcessMessageDataDone could not find object for internet mail name %s\n", sl->str); else { dprintf("got object %i for name %s\n",object_val.v.data,sl->str); SendStringMailToObject(string_id,object_val.v.data); } sl = sl->next; } LeaveServerLock(); ClearSMTPBuffers(smtp); }
void ServiceTimers(void) { MSG msg; INT64 ms; StartupComplete(); /* for the interface to report no errors on startup */ InterfaceUpdate(); lprintf("Status: %i accounts\n",GetNextAccountID()); lprintf("-------------------------------------------------------------------------------------\n"); dprintf("-------------------------------------------------------------------------------------\n"); eprintf("-------------------------------------------------------------------------------------\n"); in_main_loop = True; SetWindowText(hwndMain, ConfigStr(CONSOLE_CAPTION)); AsyncSocketStart(); for(;;) { if (timers == NULL) ms = 500; else { ms = timers->time - GetMilliCount(); if (ms <= 0) ms = 0; if (ms > 500) ms = 500; } if (MsgWaitForMultipleObjects(0,NULL,0,(DWORD)ms,QS_ALLINPUT) == WAIT_OBJECT_0) { while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if (msg.message == WM_QUIT) { lprintf("ServiceTimers shutting down the server\n"); return; } switch (msg.message) { case WM_BLAK_MAIN_READ : EnterServerLock(); PollSession(msg.lParam); TimerActivate(); LeaveServerLock(); break; case WM_BLAK_MAIN_RECALIBRATE : /* new soonest timer, so we should recalculate our time left... so we just need to restart the loop! */ break; case WM_BLAK_MAIN_DELETE_ACCOUNT : EnterServerLock(); DeleteAccountAndAssociatedUsersByID(msg.lParam); LeaveServerLock(); break; case WM_BLAK_MAIN_VERIFIED_LOGIN : EnterServerLock(); VerifiedLoginSession(msg.lParam); LeaveServerLock(); break; case WM_BLAK_MAIN_LOAD_GAME : EnterServerLock(); LoadFromKod(msg.lParam); LeaveServerLock(); break; default : dprintf("ServiceTimers got unknown message %i\n",msg.message); break; } } } else { /* a Blakod timer is ready to go */ EnterServerLock(); PollSessions(); /* really just need to check session timers */ TimerActivate(); LeaveServerLock(); } } }
void CreateAccountFromBuffer(char *buf) { char *line; char *version,*name,*password; version = name = password = NULL; line = strtok(buf,"\r\n"); while (line != NULL) { /* if (ConfigBool(DEBUG_SMTP)) { dprintf(": %i %s\n",strlen(line),line); Sleep(500); } */ if (strcmp(line,"VERSION:") == 0) version = strtok(NULL,"\r\n"); if (strcmp(line,"NAME:") == 0) name = strtok(NULL,"\r\n"); if (strcmp(line,"PASSWORD:"******"\r\n"); line = strtok(NULL,"\r\n"); } if (version == NULL) { eprintf("CreateAccountFromBuffer got no version\n"); return; } if (strcmp(version,"2") != 0) { eprintf("CreateAccountFromBuffer got version != 2 (%s)\n",version); return; } if (name == NULL || password == NULL) { eprintf("CreateAccountFromBuffer got email w/o name or password\n"); return; } if (strlen(name) > MAX_LOGIN_NAME || strlen(password) > MAX_LOGIN_PASSWORD) { eprintf("CreateAccountFromBuffer got name or password too long\n"); return; } if (strlen(name) < 3 || strlen(password) < 3) { eprintf("CreateAccountFromBuffer got charname or password too short\n"); return; } EnterServerLock(); CreateNewAccountAndCharacter(name,password); LeaveServerLock(); }
void RunMainLoop(void) { INT64 ms; const uint32_t num_notify_events = 500; struct epoll_event notify_events[num_notify_events]; int i; signal(SIGPIPE, SIG_IGN); while (!GetQuit()) { ms = GetMainLoopWaitTime(); // wait up to ms, dispatch any socket events int val = epoll_wait(fd_epoll, notify_events, num_notify_events, ms); if (val == -1) { eprintf("RunMainLoop error on epoll_wait %s\n", GetLastErrorStr()); } //printf("got events %i %lu\n", val, ms); for (i=0;i<val;i++) { if (notify_events[i].events == 0) continue; if (IsAcceptingSocket(notify_events[i].data.fd)) { if (notify_events[i].events & ~EPOLLIN) { eprintf("RunMainLoop error on accepting socket %i\n",notify_events[i].data.fd); } else { AsyncSocketAccept(notify_events[i].data.fd,FD_ACCEPT,0,GetAcceptingSocketConnectionType(notify_events[i].data.fd)); } } else { if (notify_events[i].events & ~(EPOLLIN | EPOLLOUT)) { // this means there was an error AsyncSocketSelect(notify_events[i].data.fd,0,1); } else { if (notify_events[i].events & EPOLLIN) { AsyncSocketSelect(notify_events[i].data.fd,FD_READ,0); } if (notify_events[i].events & EPOLLOUT) { AsyncSocketSelect(notify_events[i].data.fd,FD_WRITE,0); } } } } EnterServerLock(); PollSessions(); /* really just need to check session timers */ TimerActivate(); LeaveServerLock(); } close(fd_epoll); }
void AsyncSocketAccept(SOCKET sock,int event,int error,int connection_type) { SOCKET new_sock; SOCKADDR_IN acc_sin; /* Accept socket address - internet style */ int acc_sin_len; /* Accept socket address length */ SOCKADDR_IN peer_info; int peer_len; struct in_addr peer_addr; connection_node conn; session_node *s; if (event != FD_ACCEPT) { eprintf("AsyncSocketAccept got non-accept %i\n",event); return; } if (error != 0) { eprintf("AsyncSocketAccept got error %i\n",error); return; } acc_sin_len = sizeof acc_sin; new_sock = accept(sock,(struct sockaddr *) &acc_sin,&acc_sin_len); if (new_sock == SOCKET_ERROR) { eprintf("AcceptSocketConnections accept failed, error %i\n", GetLastError()); return; } peer_len = sizeof peer_info; if (getpeername(new_sock,(SOCKADDR *)&peer_info,&peer_len) < 0) { eprintf("AcceptSocketConnections getpeername failed error %i\n", GetLastError()); return; } memcpy(&peer_addr,(long *)&(peer_info.sin_addr),sizeof(struct in_addr)); memcpy(&conn.addr, &peer_addr, sizeof(struct in_addr)); sprintf(conn.name,"%s",inet_ntoa(peer_addr)); // Too out following line to prevent log files from becoming spammed with extra lines. // This line is extraneous because the outcome of the authentication is always posted to logs. // lprintf("Got connection from %s to be authenticated.\n", conn.name); if (connection_type == SOCKET_MAINTENANCE_PORT) { if (!CheckMaintenanceMask(&peer_info,peer_len)) { lprintf("Blocked maintenance connection from %s.\n", conn.name); closesocket(new_sock); return; } } else { if (!CheckBlockList(&peer_addr)) { lprintf("Blocked connection from %s.\n", conn.name); closesocket(new_sock); return; } } conn.type = CONN_SOCKET; conn.socket = new_sock; EnterServerLock(); s = CreateSession(conn); if (s != NULL) { StartAsyncSession(s); switch (connection_type) { case SOCKET_PORT : InitSessionState(s,STATE_SYNCHED); break; case SOCKET_MAINTENANCE_PORT : InitSessionState(s,STATE_MAINTENANCE); break; default : eprintf("AcceptSocketConnections got invalid connection type %i\n",connection_type); } /* need to do this AFTER s->conn is set in place, because the async call writes to that mem address */ if (ConfigBool(SOCKET_DNS_LOOKUP)) { s->conn.hLookup = StartAsyncNameLookup((char *)&peer_addr,s->conn.peer_data); } else { s->conn.hLookup = 0; } } LeaveServerLock(); }