int chat_kick( int unum, char *msg ) { char *twit = nextword(&msg); int rnum = users[unum].room; int recunum; if (!OPERATOR(unum) && !MANAGER(unum)) { send_to_unum(unum, "*** You're not operator\n", -1); return 0; } if ((recunum = chatid_to_indx(twit)) == -1) { /* no such user */ sprintf(genbuf, "*** No such chatid '%s'\n", twit); send_to_unum(unum, genbuf, -1); return 0; } if (rnum != users[recunum].room) { sprintf(genbuf, "*** '%s' is not in this room\n", users[recunum].chatid); send_to_unum(unum, genbuf, -1); return 0; } exit_room(recunum, EXIT_KICK, msg); if (rnum == 0) logout_user(recunum); else enter_room(recunum, mainroom, (char *)NULL); return 0; }
void logout(void) { struct user *tmpuser; char *uname; struct btmp btmp; uname = get_name("Name of user to log out? ", 2); if (*uname) { if (!(tmpuser = getuser(uname))) printf("There is no user %s on this BBS.\n", uname); else { if (tmpuser->f_prog && !ouruser->f_prog) printf("Can't do that!\n"); else if (!is_online(&btmp, tmpuser, NULL)) printf("%s is not online.\n", uname); else logout_user(tmpuser, NULL, 0); freeuser(tmpuser); } } }
int chat_query_chatid( int unum, char *msg ) { USERDATA udata; int recunum; char *recipient = nextword(&msg); send_to_unum(unum, "***\n", -1); if (*recipient == '\0') { /* map all chatids to userids */ return (chat_map_chatids(unum)); } recunum = fuzzy_chatid_to_indx(recipient); if (recunum < 0) { /* no such user, or ambiguous */ if (recunum == -1) sprintf(genbuf, "*** No such chatid '%s'\n", recipient); else sprintf(genbuf, "*** '%s' is ambiguous: try more letters", recipient); send_to_unum(unum, genbuf, -1); return 0; } if (utable_get_record(users[recunum].utent, &udata) != S_OK || strcmp(users[recunum].userid, udata.u.userid) || udata.u.mode != M_CHAT) { sprintf(genbuf, "*** '%s' is apparently no longer here\n", users[recunum].userid); send_to_unum(unum, genbuf, -1); exit_room(recunum, EXIT_LOSTCONN, (char *)NULL); logout_user(recunum); return 0; } sprintf(genbuf, "*** %s is %s (%s)\n", users[recunum].chatid, udata.u.userid, udata.u.username); send_to_unum(unum, genbuf, -1); sprintf(genbuf, "*** Logged in from %s\n", udata.u.fromhost); send_to_unum(unum, genbuf, -1); return 0; }
void logout_all(void) { register int i; printf("Are you are you want to logout all users on the BBS? (Y/N) -> "); if (yesno(-1)) { printf("\nLogging off all users..."); fflush(stdout); for (i = 0; i < MAXUSERS; i++) if (bigbtmp->btmp[i].pid != pid) logout_user(NULL, &bigbtmp->btmp[i], 0); mysleep(10); printf("\n\nForcing off any stragglers..."); fflush(stdout); for (i = 0; i < MAXUSERS; i++) if (bigbtmp->btmp[i].pid != pid) logout_user(NULL, &bigbtmp->btmp[i], 1); mysleep(5); putchar('\n'); } }
void check_heartbeats() { int i, d; STATUS_RESPONSE res; res.type = HEARTBEAT; res.status = SERVER_DESC.client_msgid; for (i = 0; i < SERVER_CAPACITY; i++) { d = local_client_tick_time(i); if (d <= 0) { log_write("DEAD@%d: %s\n", SERVER_DESC.server_msgid, LOCAL_CLIENTS[i].name); logout_user(LOCAL_CLIENTS[i].name); } else if (d == TIMEOUT) { msgsnd(LOCAL_CLIENTS[i].client_msgid, &res, sizeof(res)-sizeof(long), 0); } } }
/** * Free Database Memory */ void free_database(void) { // There are users playing if(_db_user_count > 0) { // Send Shutdown Notice spread_message(NULL, SERVER_SHUTDOWN_MESSAGE); } // Iterate Users for Deletion SceNetAdhocctlUserNode * user = _db_user; while(user != NULL) { // Next User (for safe delete) SceNetAdhocctlUserNode * next = user->next; // Logout User logout_user(user); // Move Pointer user = next; } }
/** * Server Main Loop * @param server Server Listening Socket * @return OS Error Code */ int server_loop(int server) { // Set Running Status _status = 1; // Create Empty Status Logfile update_status(); // Handling Loop while(_status == 1) { // Login Block { // Login Result int loginresult = 0; // Login Processing Loop do { // Prepare Address Structure struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); memset(&addr, 0, sizeof(addr)); // Accept Login Requests // loginresult = accept4(server, (struct sockaddr *)&addr, &addrlen, SOCK_NONBLOCK); // Alternative Accept Approach (some Linux Kernel don't support the accept4 Syscall... wtf?) loginresult = accept(server, (struct sockaddr *)&addr, &addrlen); if(loginresult != -1) { // Switch Socket into Non-Blocking Mode change_blocking_mode(loginresult, 1); } // Login User (Stream) if(loginresult != -1) login_user_stream(loginresult, addr.sin_addr.s_addr); } while(loginresult != -1); } // Receive Data from Users SceNetAdhocctlUserNode * user = _db_user; while(user != NULL) { // Next User (for safe delete) SceNetAdhocctlUserNode * next = user->next; // Receive Data from User int recvresult = recv(user->stream, user->rx + user->rxpos, sizeof(user->rx) - user->rxpos, 0); // Connection Closed or Timed Out if(recvresult == 0 || (recvresult == -1 && errno != EAGAIN && errno != EWOULDBLOCK) || get_user_state(user) == USER_STATE_TIMED_OUT) { // Logout User logout_user(user); } // Received Data (or leftovers in RX-Buffer) else if(recvresult > 0 || user->rxpos > 0) { // New Incoming Data if(recvresult > 0) { // Move RX Pointer user->rxpos += recvresult; // Update Death Clock user->last_recv = time(NULL); } // Waiting for Login Packet if(get_user_state(user) == USER_STATE_WAITING) { // Valid Opcode if(user->rx[0] == OPCODE_LOGIN) { // Enough Data available if(user->rxpos >= sizeof(SceNetAdhocctlLoginPacketC2S)) { // Clone Packet SceNetAdhocctlLoginPacketC2S packet = *(SceNetAdhocctlLoginPacketC2S *)user->rx; // Remove Packet from RX Buffer clear_user_rxbuf(user, sizeof(SceNetAdhocctlLoginPacketC2S)); // Login User (Data) login_user_data(user, &packet); } } // Invalid Opcode else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; printf("Invalid Opcode 0x%02X in Waiting State from %u.%u.%u.%u.\n", user->rx[0], ip[0], ip[1], ip[2], ip[3]); // Logout User logout_user(user); } } // Logged-In User else if(get_user_state(user) == USER_STATE_LOGGED_IN) { // Ping Packet if(user->rx[0] == OPCODE_PING) { // Delete Packet from RX Buffer clear_user_rxbuf(user, 1); } // Group Connect Packet else if(user->rx[0] == OPCODE_CONNECT) { // Enough Data available if(user->rxpos >= sizeof(SceNetAdhocctlConnectPacketC2S)) { // Cast Packet SceNetAdhocctlConnectPacketC2S * packet = (SceNetAdhocctlConnectPacketC2S *)user->rx; // Clone Group Name SceNetAdhocctlGroupName group = packet->group; // Remove Packet from RX Buffer clear_user_rxbuf(user, sizeof(SceNetAdhocctlConnectPacketC2S)); // Change Game Group connect_user(user, &group); } } // Group Disconnect Packet else if(user->rx[0] == OPCODE_DISCONNECT) { // Remove Packet from RX Buffer clear_user_rxbuf(user, 1); // Leave Game Group disconnect_user(user); } // Network Scan Packet else if(user->rx[0] == OPCODE_SCAN) { // Remove Packet from RX Buffer clear_user_rxbuf(user, 1); // Send Network List send_scan_results(user); } // Chat Text Packet else if(user->rx[0] == OPCODE_CHAT) { // Enough Data available if(user->rxpos >= sizeof(SceNetAdhocctlChatPacketC2S)) { // Cast Packet SceNetAdhocctlChatPacketC2S * packet = (SceNetAdhocctlChatPacketC2S *)user->rx; // Clone Buffer for Message char message[64]; memset(message, 0, sizeof(message)); strncpy(message, packet->message, sizeof(message) - 1); // Remove Packet from RX Buffer clear_user_rxbuf(user, sizeof(SceNetAdhocctlChatPacketC2S)); // Spread Chat Message spread_message(user, message); } } // Invalid Opcode else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; printf("Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u).\n", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3]); // Logout User logout_user(user); } } } // Move Pointer user = next; } // Prevent needless CPU Overload (1ms Sleep) usleep(1000); } // Free User Database Memory free_database(); // Close Server Socket close(server); // Return Success return 0; }
int main() { pthread_t tid1; pthread_attr_t attr; pthread_attr_init(&attr); int temp=0, n; pthread_create(&tid1, &attr, load_check, (void *)temp); int shmid1; key_t key1; char *shm1, *s1; key1 = 5000; if ((shmid1 = shmget(key1, MAX, IPC_CREAT | 0666)) < 0) { perror("shmget"); exit(1); } if ((shm1 = shmat(shmid1, NULL, 0)) == (char *) -1) { perror("shmat"); exit(1); } char *str1 = "exit"; char *str2; while(1) { if(*shm1=='^') { *shm1='@'; while(*shm1=='@') sleep(1); while(1) { str2=shm1; if((strncmp(str1,str2,4))==0) { break; } for (s1 = shm1; *s1 != NULL; s1++) putchar(*s1); putchar('\n'); *shm1 = '*'; while(*shm1=='*') sleep(1); } *shm1='$'; } printf("Select an option\n1. View all running processes\n2. Duration from which a process is running\n3. CPU and memory utilization of all processes\n4. Terminate a process\n5. View all logged in users\n6. Logout an user\n7. Send message to all users\n8. Exit\n"); scanf("%d", &n); switch(n) { case 1: view_processes(); break; case 2: view_duration(); break; case 3: view_utilization(); break; case 4: terminate_process(); break; case 5: view_users(); break; case 6: logout_user(); break; case 7: *shm1='^'; while(*shm1 == '^') sleep(1); while(*shm1 != '$') { s1 = shm1; printf("Enter the message you want to send to all users\n"); gets(s1); while (*shm1 != '*' && *shm1 != '$') sleep(1); } break; case 8: return; break; } } pthread_join(tid1,NULL); }
int login_user( int unum, char *msg ) { int i, utent, fd = users[unum].sockfd; char accessbytes[MAX_CLNTCMDS]; char *utentstr = nextword(&msg); char *chatid = nextword(&msg); USERDATA udata; PATH ignorefile; utent = atoi(utentstr); if (utable_get_record(utent, &udata) != S_OK || udata.u.mode != M_CHAT) { send_to_unum(unum, CHAT_LOGIN_BOGUS, -1); return -1; } for (i=0; i<bbs_max_users; i++) { if (users[i].sockfd != -1 && users[i].utent == utent) { /* Either a "ghost" or a hacker */ if (kill(users[i].client_pid, 0) == 0) { send_to_unum(unum, CHAT_LOGIN_BOGUS, -1); return -1; } else { exit_room(i, EXIT_LOSTCONN, (char *)NULL); logout_user(i); } } } if (strlen(chatid) > CHATID_MAX) chatid[CHATID_MAX] = '\0'; if (!is_valid_chatid(chatid)) { send_to_unum(unum, CHAT_LOGIN_INVALID, -1); return 0; /* TODO change to -1 when possible */ } if (chatid_to_indx(chatid) != -1) { /* userid in use */ send_to_unum(unum, CHAT_LOGIN_EXISTS, -1); return 0; /* TODO: change to -1 when possible */ } /* Login is ok. Set flags and fill in user record. */ utable_get_record(utent, &udata); if (udata.u.flags & FLG_CLOAK) { udata.u.flags &= ~FLG_CLOAK; users[unum].flags |= FLG_RESTORECLOAK; } utable_set_record(utent, &udata); if (is_in_namelist(manager_list, udata.u.userid)) users[unum].flags |= FLG_CHATMGR; else if (is_in_namelist(restricted_list, udata.u.userid)) users[unum].flags |= FLG_CHATGUEST; users[unum].utent = utent; users[unum].client_pid = udata.u.pid; strncpy(users[unum].userid, udata.u.userid, NAMELEN); if (!RESTRICTED(unum)) { chat_get_ignore_file(users[unum].userid, ignorefile); read_namelist(ignorefile, &users[unum].ignorelist); } users[unum].ignoring = NULL; for (i = 0; i < bbs_max_users; i++) { if (users[i].sockfd == -1) continue; if (is_in_namelist(users[i].ignorelist, udata.u.userid)) { if (users[unum].ignoring == NULL) users[unum].ignoring = (char *)calloc(bbs_max_users, sizeof(char)); if (users[unum].ignoring != NULL) users[unum].ignoring[i] = 1; } if (is_in_namelist(users[unum].ignorelist, users[i].userid)) { if (users[i].ignoring == NULL) users[i].ignoring = (char *)calloc(bbs_max_users, sizeof(char)); if (users[i].ignoring != NULL) users[i].ignoring[unum] = 1; } } strcpy(users[unum].chatid, chatid); send_to_unum(unum, CHAT_LOGIN_OK, -1); sprintf(genbuf, "*** Welcome to Chat, %s\n", users[unum].chatid); send_to_unum(unum, genbuf, -1); display_motd(unum); print_user_counts(unum); enter_room(unum, mainroom, (char *)NULL); return 0; }
int main( int argc, char *argv[] ) { struct sockaddr_in sin; register int i; int pid, sr, newsock, sinsize; fd_set readfds; struct timeval *tvptr = NULL; if (argc < 2) { fprintf(stderr, "Usage: %s numusers\n" ,argv[0]); return 1; } bbs_max_users = atoi(argv[1]); if (bbs_max_users == 0) { fprintf(stderr, "maxusers cannot be zero\n"); return 1; } manager_list = restricted_list = NULL; strcpy(mainroom, "main"); chat_init_config(); users = (struct chatuser *)calloc(bbs_max_users, sizeof(*users)); if (users == NULL) { perror("calloc"); return 1; } for (i=0; i<bbs_max_users; i++) users[i].sockfd = users[i].utent = -1; rooms = (struct chatroom *)calloc(bbs_max_users, sizeof(*rooms)); if (rooms == NULL || (rooms[0].invites = (char *)malloc(bbs_max_users)) == NULL) { perror("calloc"); return 1; } strcpy(rooms[0].name, mainroom); if (utable_attach(bbs_max_users) != S_OK) { fprintf(stderr, "cannot attach to utable\n"); return 1; } if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit_chatd(1, "socket failed"); } sin.sin_family = AF_INET; sin.sin_port = 0; sin.sin_addr.s_addr = INADDR_ANY; if (bind(sock, (struct sockaddr *)&sin, sizeof sin) == -1) { perror("bind"); exit_chatd(1, "bind failed"); } sinsize = sizeof sin; if (getsockname(sock, (struct sockaddr *)&sin, &sinsize) == -1) { perror("getsockname"); exit_chatd(1, "getsockname failed"); } if (listen(sock, SOMAXCONN) == -1) { perror("listen"); exit_chatd(1, "listen failed"); } /* race condition here if two daemons start up at once? */ _write_daemoninfo(PATH_CHATPORT, htons(sin.sin_port)); #ifndef DEBUG switch (pid = fork()) { case -1: perror("fork"); exit_chatd(1, "fork failed"); case 0: setpgid(0, 0); break; default: /* Assuming that a pid fits into a ushort may be a bad idea. */ _write_daemoninfo(PATH_CHATPID, (unsigned short)pid); return 0; } #else printf("Server bound to port %d\n", htons(sin.sin_port)); #endif signal(SIGHUP, sig_catcher); signal(SIGINT, sig_catcher); #ifndef DEBUG signal(SIGQUIT, sig_catcher); #endif signal(SIGILL, sig_catcher); signal(SIGIOT, sig_catcher); #ifdef SIGEMT signal(SIGEMT, sig_catcher); #endif signal(SIGFPE, sig_catcher); #ifdef SIGBUS signal(SIGBUS, sig_catcher); #endif signal(SIGSEGV, sig_catcher); #ifdef SIGSYS signal(SIGSYS, sig_catcher); #endif signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sig_catcher); signal(SIGALRM, SIG_IGN); #ifdef SIGIO signal(SIGIO, SIG_IGN); #endif #ifdef SIGURG signal(SIGURG, SIG_IGN); #endif #ifdef SIGPWR signal(SIGPWR, sig_catcher); #endif FD_ZERO(&allfds); FD_SET(sock, &allfds); nfds = sock+1; while (1) { memcpy(&readfds, &allfds, sizeof readfds); #ifdef DEBUG printf("Selecting..."); #endif sr = select(nfds, &readfds, NULL, NULL, tvptr); #ifdef DEBUG printf("done: returned %d\n", sr); #endif if (sr == 0) { exit_chatd(0, "normal chat server shutdown"); } if (sr == -1) { if (errno == EINTR) continue; else { exit_chatd(1, "select failed"); } } if (tvptr) tvptr = NULL; if (FD_ISSET(sock, &readfds)) { sinsize = sizeof sin; newsock = accept(sock, (struct sockaddr *)&sin, &sinsize); if (newsock == -1) { #ifdef DEBUG printf("accept failed: errno %d\n", errno); #endif continue; } for (i=0; i<bbs_max_users; i++) { if (users[i].sockfd == -1) { users[i].sockfd = newsock; users[i].room = -1; users[i].ibufsize = 0; #ifdef DEBUG printf("Connection to slot %2d, fd %d\n", i, newsock); #endif break; } } if (i >= bbs_max_users) { /* full -- no more chat users */ close(newsock); } else { #ifndef RELIABLE_SELECT_FOR_WRITE int flags = fcntl(newsock, F_GETFL, 0); flags |= O_NDELAY; fcntl(newsock, F_SETFL, flags); #endif FD_SET(newsock, &allfds); if (newsock >= nfds) nfds = newsock+1; num_conns++; } } for (i=0; i<bbs_max_users; i++) { /* we are done with newsock, so re-use the variable */ newsock = users[i].sockfd; if (newsock != -1 && FD_ISSET(newsock, &readfds)) { if (process_chat_command(i) == -1) { logout_user(i); /* this clear the bit in allfds & dec. num_conns */ } } } if (num_conns <= 0) { /* one more pass at select, then we go bye-bye */ tvptr = &zerotv; } } /*NOTREACHED*/ return 0; }
void handle_logout(const void * req) { CLIENT_REQUEST * cr = (CLIENT_REQUEST*) req; logout_user(cr->client_name); }
/** * Login User into Database (Login Data) * @param user User Node * @param data Login Packet */ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S * data) { // Product Code Check int valid_product_code = 1; // Iterate Characters int i = 0; for(; i < PRODUCT_CODE_LENGTH && valid_product_code == 1; i++) { // Valid Characters if(!((data->game.data[i] >= 'A' && data->game.data[i] <= 'Z') || (data->game.data[i] >= '0' && data->game.data[i] <= '9'))) valid_product_code = 0; } // Valid Packet Data if(valid_product_code == 1 && memcmp(&data->mac, "\xFF\xFF\xFF\xFF\xFF\xFF", sizeof(data->mac)) != 0 && memcmp(&data->mac, "\x00\x00\x00\x00\x00\x00", sizeof(data->mac)) != 0 && data->name.data[0] != 0) { // Game Product Override game_product_override(&data->game); // Find existing Game SceNetAdhocctlGameNode * game = _db_game; while(game != NULL && strncmp(game->game.data, data->game.data, PRODUCT_CODE_LENGTH) != 0) game = game->next; // Game not found if(game == NULL) { // Allocate Game Node Memory game = (SceNetAdhocctlGameNode *)malloc(sizeof(SceNetAdhocctlGameNode)); // Allocated Game Node Memory if(game != NULL) { // Clear Memory memset(game, 0, sizeof(SceNetAdhocctlGameNode)); // Save Game Product ID game->game = data->game; // Link into Game List game->next = _db_game; if(_db_game != NULL) _db_game->prev = game; _db_game = game; } } // Game now available if(game != NULL) { // Save MAC user->resolver.mac = data->mac; // Save Nickname user->resolver.name = data->name; // Increase Player Count in Game Node game->playercount++; // Link Game to Player user->game = game; // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, game->game.data, PRODUCT_CODE_LENGTH); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) started playing %s.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); // Update Status Log update_status(); // Leave Function return; } } // Invalid Packet Data else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; printf("Invalid Login Packet Contents from %u.%u.%u.%u.\n", ip[0], ip[1], ip[2], ip[3]); } // Logout User - Out of Memory or Invalid Arguments logout_user(user); }
/** * Spread Chat Message in P2P Network * @param user Sender User Node * @param message Chat Message */ void spread_message(SceNetAdhocctlUserNode * user, char * message) { // Global Notice if(user == NULL) { // Iterate Players for(user = _db_user; user != NULL; user = user->next) { // Player has access to chat if(user->group != NULL) { // Chat Packet SceNetAdhocctlChatPacketS2C packet; // Clear Memory memset(&packet, 0, sizeof(packet)); // Set Chat Opcode packet.base.base.opcode = OPCODE_CHAT; // Set Chat Message strcpy(packet.base.message, message); // Send Data send(user->stream, &packet, sizeof(packet), 0); } } // Prevent NULL Error return; } // User is connected else if(user->group != NULL) { // Broadcast Range Counter uint32_t counter = 0; // Iterate Group Players SceNetAdhocctlUserNode * peer = user->group->player; while(peer != NULL) { // Skip Self if(peer == user) { // Move Pointer peer = peer->group_next; // Continue Loop continue; } // Chat Packet SceNetAdhocctlChatPacketS2C packet; // Set Chat Opcode packet.base.base.opcode = OPCODE_CHAT; // Set Chat Message strcpy(packet.base.message, message); // Set Sender Nickname packet.name = user->resolver.name; // Send Data send(peer->stream, &packet, sizeof(packet), 0); // Move Pointer peer = peer->group_next; // Increase Broadcast Range Counter counter++; } // Message Sent if(counter > 0) { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) sent \"%s\" to %d players in %s group %s.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], message, counter, safegamestr, safegroupstr); } // Exit Function return; } // User not in a game group else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to send a text message without joining a %s group first.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); } // Delete User logout_user(user); }
/** * Send Game Group List * @param user User Node */ void send_scan_results(SceNetAdhocctlUserNode * user) { // User is disconnected if(user->group == NULL) { // Iterate Groups SceNetAdhocctlGroupNode * group = user->game->group; for(; group != NULL; group = group->next) { // Scan Result Packet SceNetAdhocctlScanPacketS2C packet; // Clear Memory // memset(&packet, 0, sizeof(packet)); // Set Opcode packet.base.opcode = OPCODE_SCAN; // Set Group Name packet.group = group->group; // Iterate Players in Network Group SceNetAdhocctlUserNode * peer = group->player; for(; peer != NULL; peer = peer->group_next) { // Found Network Founder if(peer->group_next == NULL) { // Set Group Host MAC packet.mac = peer->resolver.mac; } } // Send Group Packet send(user->stream, &packet, sizeof(packet), 0); } // Notify Player of End of Scan uint8_t opcode = OPCODE_SCAN_COMPLETE; send(user->stream, &opcode, 1, 0); // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) requested information on %d %s groups.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], user->game->groupcount, safegamestr); // Exit Function return; } // User in a game group else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to scan for %s groups without disconnecting from %s first.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); } // Delete User logout_user(user); }
/** * Disconnect User from Game Group * @param user User Node */ void disconnect_user(SceNetAdhocctlUserNode * user) { // User is connected if(user->group != NULL) { // Unlink Leftside (Beginning) if(user->group_prev == NULL) user->group->player = user->group_next; // Unlink Leftside (Other) else user->group_prev->group_next = user->group_next; // Unlink Rightside if(user->group_next != NULL) user->group_next->group_prev = user->group_prev; // Fix Player Count user->group->playercount--; // Iterate remaining Group Players SceNetAdhocctlUserNode * peer = user->group->player; while(peer != NULL) { // Disconnect Packet SceNetAdhocctlDisconnectPacketS2C packet; // Clear Memory // memset(&packet, 0, sizeof(packet)); // Set Disconnect Opcode packet.base.opcode = OPCODE_DISCONNECT; // Set User IP packet.ip = user->resolver.ip; // Send Data send(peer->stream, &packet, sizeof(packet), 0); // Move Pointer peer = peer->group_next; } // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) left %s group %s.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); // Empty Group if(user->group->playercount == 0) { // Unlink Leftside (Beginning) if(user->group->prev == NULL) user->group->game->group = user->group->next; // Unlink Leftside (Other) else user->group->prev->next = user->group->next; // Unlink Rightside if(user->group->next != NULL) user->group->next->prev = user->group->prev; // Free Group Memory free(user->group); // Decrease Group Counter in Game Node user->game->groupcount--; } // Unlink from Group user->group = NULL; user->group_next = NULL; user->group_prev = NULL; // Update Status Log update_status(); // Exit Function return; } // Not in a game group else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to leave %s group without joining one first.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); } // Delete User logout_user(user); }
/** * Connect User to Game Group * @param user User Node * @param group Group Name */ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group) { // Group Name Check int valid_group_name = 1; { // Iterate Characters int i = 0; for(; i < ADHOCCTL_GROUPNAME_LEN && valid_group_name == 1; i++) { // End of Name if(group->data[i] == 0) break; // A - Z if(group->data[i] >= 'A' && group->data[i] <= 'Z') continue; // a - z if(group->data[i] >= 'a' && group->data[i] <= 'z') continue; // 0 - 9 if(group->data[i] >= '0' && group->data[i] <= '9') continue; // Invalid Symbol valid_group_name = 0; } } // Valid Group Name if(valid_group_name == 1) { // User is disconnected if(user->group == NULL) { // Find Group in Game Node SceNetAdhocctlGroupNode * g = user->game->group; while(g != NULL && strncmp((char *)g->group.data, (char *)group->data, ADHOCCTL_GROUPNAME_LEN) != 0) g = g->next; // BSSID Packet SceNetAdhocctlConnectBSSIDPacketS2C bssid; // Set BSSID Opcode bssid.base.opcode = OPCODE_CONNECT_BSSID; // Set Default BSSID bssid.mac = user->resolver.mac; // No Group found if(g == NULL) { // Allocate Group Memory g = (SceNetAdhocctlGroupNode *)malloc(sizeof(SceNetAdhocctlGroupNode)); // Allocated Group Memory if(g != NULL) { // Clear Memory memset(g, 0, sizeof(SceNetAdhocctlGroupNode)); // Link Game Node g->game = user->game; // Link Group Node g->next = g->game->group; if(g->game->group != NULL) g->game->group->prev = g; g->game->group = g; // Copy Group Name g->group = *group; // Increase Group Counter for Game g->game->groupcount++; } } // Group now available if(g != NULL) { // Iterate remaining Group Players SceNetAdhocctlUserNode * peer = g->player; while(peer != NULL) { // Connect Packet SceNetAdhocctlConnectPacketS2C packet; // Clear Memory // memset(&packet, 0, sizeof(packet)); // Set Connect Opcode packet.base.opcode = OPCODE_CONNECT; // Set Player Name packet.name = user->resolver.name; // Set Player MAC packet.mac = user->resolver.mac; // Set Player IP packet.ip = user->resolver.ip; // Send Data send(peer->stream, &packet, sizeof(packet), 0); // Set Player Name packet.name = peer->resolver.name; // Set Player MAC packet.mac = peer->resolver.mac; // Set Player IP packet.ip = peer->resolver.ip; // Send Data send(user->stream, &packet, sizeof(packet), 0); // Set BSSID if(peer->group_next == NULL) bssid.mac = peer->resolver.mac; // Move Pointer peer = peer->group_next; } // Link User to Group user->group_next = g->player; if(g->player != NULL) g->player->group_prev = user; g->player = user; // Link Group to User user->group = g; // Increase Player Count g->playercount++; // Send Network BSSID to User send(user->stream, &bssid, sizeof(bssid), 0); // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) joined %s group %s.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); // Update Status Log update_status(); // Exit Function return; } } // Already connected to another group else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)group->data, ADHOCCTL_GROUPNAME_LEN); char safegroupstr2[9]; memset(safegroupstr2, 0, sizeof(safegroupstr2)); strncpy(safegroupstr2, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join %s group %s without disconnecting from %s first.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr, safegroupstr2); } } // Invalid Group Name else { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)group->data, ADHOCCTL_GROUPNAME_LEN); printf("%s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join invalid %s group %s.\n", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); } // Invalid State, Out of Memory or Invalid Group Name logout_user(user); }