void spawn_tile_collision (Spawn *self, Tile *tile, Map *map) { /* Kartenrand / unbegehbar */ if(self->x >= map->x || self->y >= map->y || !tile_can_walk(*tile)) { /* umkehren */ switch(self->direction) { case NORTH: self->y++; break; case SOUTH: self->y--; break; case EAST: self->x--; break; case WEST: self->x++; break; } if (tile->type == TILE_TYPE_WALL) { damage_spawn(self, 1, map); push_msg("Kopf -> Wand (-1HP)", map); } } else { if (tile->number_of_items > 0) { /* Items aufsammeln. */ self->inventory = ex_realloc(self->inventory, (self->inventory_size + tile->number_of_items) * sizeof(Item*)); for (unsigned int ii = 0; ii < tile->number_of_items; ++ii) { if(tile->items[ii]->type != ITEM_TYPE_INVALID) { self->inventory[++self->inventory_size - 1] = tile->items[ii]; } } /* Aufzählen, was aufgesammelt */ for(unsigned int i = 0; i < tile->number_of_items; ++i) { if(tile->items[i]->type != ITEM_TYPE_INVALID) { char* item_message = (char*)ex_calloc(22 + strlen(tile->items[i]->name), 1); sprintf(item_message, "Du hast aufgenommen: %s", tile->items[i]->name); push_msg(item_message, map); free(item_message); } } self->selected_item=self->inventory_size-1; free(tile->items); tile->items = NULL; tile->number_of_items = 0; } /* Ausgang */ else if(tile->type == TILE_TYPE_EXIT) { map->finished = 1; } } }
void QQ::pre_sign_in_step_2() { size_t req_size = 13; uint8_t* request = new_request(0x62, req_size); push_msg(request, req_size); delete[] request; set_state(QQ_WF_LOGINTOKEN); }
void spawn_spawn_collision (Spawn *self, Spawn *other, Map *map) { switch(self->type){ case SPAWN_TYPE_PLAYER: switch(other->type){ case SPAWN_TYPE_HOUND: damage_spawn(other, 10, map); break; case SPAWN_TYPE_ZOMBIE: damage_spawn(other, 10, map); break; default: break; } break; case SPAWN_TYPE_HOUND: switch(other->type){ case SPAWN_TYPE_PLAYER: damage_spawn(other, 5, map); push_msg("gebissen! (-5HP)", map); break; default: break; } break; case SPAWN_TYPE_ZOMBIE: switch(other->type){ case SPAWN_TYPE_PLAYER: damage_spawn(other, 10, map); push_msg("Baem! (-10HP)", map); break; default: break; } break; default: break; } }
void QQ::dispatch_msg() { uint8_t msg[messenger::BUF_SIZE] = {0}; int len = 0; int i = 0; size_t j = 0; bool match = false; char msg_info[128] = {0}; uint8_t* compare = NULL; size_t count = 0; qq_state_enum state = get_state(); if (msgr == NULL || msgr->get_incoming_msg_queue_size() == 0) { return; } pthread_mutex_lock(&srv_ip_mtx); switch (state) { case QQ_WF_PREFIRST: case QQ_WF_REDIRECT: if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (len < 10) { break; } // count = hex_string_to_bytes("02030000310004010003" , &compare); count = hex_string_to_bytes("02000000310004010003" , &compare); //2009-08-06 if (memcmp((char*)msg, compare, count) == 0) { delay(200); set_state(QQ_LOGINTOKEN); } delete[] compare; break; case QQ_WF_LOGINTOKEN: if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { cout << "Read NONE!" << endl; break; } if (len >= 34) { // 请求登录令牌的命令号 0x0062 count = hex_string_to_bytes("020e35006200000018", &compare); match = true; for (j = 0; j < count; j++) { if (j == 5 || j == 6) continue; if (msg[j] != compare[j]) { match = false; break; } } delete[] compare; } if (match) { pthread_mutex_lock(&login_token_mtx); for (j = 0; j < 24; j++) login_token[j] = msg[j + 9]; pthread_mutex_unlock(&login_token_mtx); delay(200); set_state(QQ_LOGIN_IN); } break; case QQ_WF_LOGIN_IN: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (len < 32) { printf("QQ_WF_LOGIN_IN: len == %d < 32, break.\n", len); break; } count = hex_string_to_bytes("020e350022", &compare); if (memcmp((char*)msg, compare, count) != 0) { delete[] compare; break; } delete[] compare; if (len == 32) { delay(200); set_state(QQ_REDIRECT); //cout << "QQ_REDIRECT" << endl; pthread_mutex_lock(&rand_key_mtx); TEA tea(rand_key); pthread_mutex_unlock(&rand_key_mtx); unsigned char * plain_msg = NULL; if (tea.qq_decrypt((msg + 7), 24, &plain_msg) != 11) { cout << "Decrypt Failed!" << endl; delay(200); set_state(QQ_ZERO); break; } unsigned int n_ip = *((unsigned int *) (plain_msg + 5)); unsigned short n_port = *((unsigned short *) (plain_msg + 9)); unsigned short h_port = ntohs(n_port); unsigned int h_ip = ntohl(n_ip); memset(srv_ip, 0, IPADDR_LEN); sprintf(srv_ip, "%d.%d.%d.%d", (h_ip >> 24) % 0x100, (h_ip >> 16) % 0x100, (h_ip >> 8) % 0x100, h_ip % 0x100); srv_port = h_port; delete[] plain_msg; break; } if (len == 88) { printf("QQ_WF_LOGIN_IN: recieved 88 bytes.\n"); } if (len != 192) { printf("QQ_WF_LOGIN_IN: len == %d != 192, login failed, try again.\n", len); set_state(QQ_ZERO); break; } uint8_t * pwhash2 = NULL; hex_string_to_bytes(qq_pw, &pwhash2); TEA tea(pwhash2); uint8_t * plain_msg = NULL; try { tea.qq_decrypt((msg + 7), 184, &plain_msg); } catch (out_of_range e) { cout << e.what() << endl; } uint32_t my_qq_id = 0; uint32_t my_ip = 0; uint16_t my_port = 0; uint32_t srv_listen_ip = 0; uint16_t srv_listen_port = 0; time_t login_time = 0; struct tm* tm_ptr; uint32_t unknown_ip = 0; switch (plain_msg[0]) { case 0x00: memcpy(session_key, plain_msg + 1, 16); delay(200); set_state(QQ_PRE_ONLINE_FIR); my_qq_id = ntohl(*((uint32_t *) (plain_msg + 17))); my_ip = ntohl(*((uint32_t *) (plain_msg + 21))); my_port = ntohs(*((uint16_t *) (plain_msg + 25))); srv_listen_ip = ntohl(*((uint32_t *) (plain_msg + 27))); srv_listen_port = ntohs(*((uint16_t *) (plain_msg + 31))); login_time = (time_t) ntohl(*((uint32_t *) (plain_msg + 33))); unknown_ip = ntohl(*((uint32_t *) (plain_msg + 63))); tm_ptr = localtime(&login_time); sprintf(client_ip_port, "%d.%d.%d.%d:%d", (my_ip >> 24) % 0x100, (my_ip >> 16) % 0x100, (my_ip >> 8) % 0x100, my_ip % 0x100, my_port); sprintf(signin_time, "%02d:%02d:%02d", tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec); sprintf(msg_info, "QQ ID:\t%d\r\nIP Addr:\t%s\r\nTime:\t\t%s", my_qq_id, client_ip_port, signin_time); log_event(msg_info); break; default: delay(200); set_state(QQ_ZERO); break; } delete[] plain_msg; delete[] pwhash2; break; } case QQ_WF_PRE_ONLINE_FIR: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } cout << "Server IP:\t" << srv_ip << ":" << srv_port << endl; if (msg[0] == 0x02 && msg[1] == 0x0e && msg[2] == 0x35) { TEA tea(session_key); unsigned char * plain_msg = NULL; tea.qq_decrypt((msg + 7), len - 8, &plain_msg); unsigned short order = msg[3] * 0x100 + msg[4]; switch (order) { case 0x6: { my_profile_gotten = true; set_state(QQ_PRE_ONLINE_SEC); break; } } delete[] plain_msg; } break; } case QQ_WF_PRE_ONLINE_SEC: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (msg[0] == 0x02 && msg[1] == 0x0e && msg[2] == 0x35) { TEA tea(session_key); unsigned char * plain_msg = NULL; int msg_len = tea.qq_decrypt((msg + 7), len - 8, &plain_msg); unsigned short order = msg[3] * 0x100 + msg[4]; switch (order) { case 0x26: { memcpy(friend_id, plain_msg, 2); if (plain_msg[0] * 0x100 + plain_msg[1] == 0xffff) { set_state(QQ_ONLINE); delay(200); } else { delay(200); set_state(QQ_PRE_ONLINE_SEC); } i = 2; while (i < msg_len) { int* pint = (int*) (plain_msg + i); int buddy_id = ntohl(*pint); unsigned char ssize = *(plain_msg + i + 8); char* nickname = new char[ssize + 1]; memset(nickname, 0, ssize + 1); memcpy(nickname, plain_msg + i + 9, ssize); char ss[20]; sprintf(ss, "<%d>", buddy_id); char* listchars = new char[ssize + 1 + 20]; strcpy(listchars, nickname); strcat(listchars, ss); string buddy_nickname = nickname; contact.insert(pair<int, string>(buddy_id, buddy_nickname)); delete[] nickname; delete[] listchars; i = i + 9 + ssize + 4; } break; } } delete[] plain_msg; } break; } case QQ_ONLINE: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (msg[0] == 0x02) { TEA tea(session_key); unsigned char * plain_msg = NULL; int msg_len = tea.qq_decrypt((msg + 7), len - 8, &plain_msg); unsigned short order = msg[3] * 0x100 + msg[4]; char signature[128]; switch (order) { case 0x02: pthread_mutex_lock(&drop_flag_mtx); drop_flag = 0; pthread_mutex_unlock(&drop_flag_mtx); break; case 0x17: { int sender_qq = ntohl(*((int*) plain_msg)); //发送者QQ号 int mlong = msg_len - 65 - plain_msg[msg_len - 1]; if (mlong > 0) { char* received_msg = new char[mlong + 1]; memset(received_msg, 0, mlong + 1); memcpy(received_msg, plain_msg + 65, mlong); if (config.set_received_msg_as_personal_msg) { strncpy((char *) signature, received_msg, 100); set_personal_msg((const char *) signature); } process_msg(sender_qq, received_msg); delete[] received_msg; /* * 回复 收到了消息 * 1. 消息发送者QQ号,4字节 * 2. 消息接收者QQ号,4字节,也就是我 * 3. 消息序号,4字节 * 4. 发送者IP,4字节 */ unsigned char * plaintext = new unsigned char[16]; memcpy(plaintext, plain_msg, 16); unsigned char * ciphertext = NULL; size_t miSize = tea.qq_encrypt(plaintext, 16, &ciphertext); size_t msg_size = miSize + 12; uint8_t* request = new_request(0x17, msg_size); request[5] = msg[5]; // TEA::Rand(); request[6] = msg[6]; // TEA::Rand(); memcpy(request + 11, ciphertext, miSize); push_msg(request, msg_size, false); delete[] plaintext; delete[] ciphertext; delete[] request; } break; } } delete [] plain_msg; } break; } default: break; }
void toggle_tile (Tile *self, Map *map) { /* Button */ if(self->type == TILE_TYPE_BUTTON) { ButtonProperties* btn_props = (ButtonProperties*)self->properties; if(btn_props->toggle_id == NULL) { return; } unsigned int map_size = map->x * map->y; Tile* to_toggle; for (unsigned int ii = 0; ii < map_size; ++ii) { to_toggle = &map->tiles[ii]; if(to_toggle->id == NULL || to_toggle == self) { continue; } if (0 == strcmp(btn_props->toggle_id, to_toggle->id)) { /* Sonderbehandlung Tür, wenn durch externen Button gedrückt */ if(to_toggle->type == TILE_TYPE_DOOR) { DoorProperties* door_props = (DoorProperties *)to_toggle->properties; /* hat externen Schalter, wird also hier getoggelt */ if(door_props->external_button) { door_props->open ^= 1; } /* sonst entscheidet der Schalter nur über Verriegelung */ else { door_props->locked ^= 1; } } /* Wand */ else if(to_toggle->type == TILE_TYPE_WALL) { WallProperties* wall_props = (WallProperties *)to_toggle->properties; wall_props->floor ^= 1; } else { toggle_tile(to_toggle, map); } break; } } } /* Tür */ else if(self->type == TILE_TYPE_DOOR) { DoorProperties* door_props = (DoorProperties *)self->properties; /* Tür hat eigenen Schalter und ist nicht verschlossen */ if(!door_props->locked) { if(!(door_props->external_button)) { door_props->open ^= 1; } } else { /* Mit Schlüssel aufschließbar */ if(door_props->key_id != NULL) { unsigned int i; Spawn* player = get_player_spawn(map); /* Inventar scannen */ for(i = 0; i < player->inventory_size; ++i) { Item* key_candidate = player->inventory[i]; if(key_candidate != NULL && key_candidate->type == ITEM_TYPE_KEY) { if(strcmp(key_candidate->id, door_props->key_id) == 0) { /* Key entfernen! */ delete_item(key_candidate, player); door_props->locked = 0; push_msg("Tuer entriegelt", map); break; } } } /* wurde nicht aufgemacht */ if(door_props->locked) { push_msg("Tuer verschlossen", map); } } } } /* Hinweis */ else if(self->type == TILE_TYPE_HINT) { HintProperties* hint_props = (HintProperties *)self->properties; if(hint_props->message != NULL) { /* Was das Ding zu sagen hat, in den Ausgabestream packen! */ push_msg(hint_props->message, map); } } }
void spawn_uses_item (Spawn *self, Item *item, Map *map) { (void)map; switch (item->type) { case ITEM_TYPE_HEALTH_POTION: self->hp += ((HealthPotionProperties *)item->properties)->capacity; if (self->hp > self->max_hp) { self->hp = self->max_hp; } push_msg("Schluck! (Heiltrank)", map); /* raus mit dem Item ... */ delete_item(item, self); break; case ITEM_TYPE_DEAD_CAT: push_msg("Miau?", map); break; case ITEM_TYPE_SHOTGUN: /*Schaden anrichten, wenn noch Muni da war*/ if(delete_item_by_type(ITEM_TYPE_SHOTGUN_AMMO, self)){ Spawn *victim=NULL; unsigned int damage=0; switch(self->direction){ case NORTH: for(unsigned int i=1;i<=10 && self->y-i+1;i++){ /*wenn da ne Wand ist, nichts tun*/ if(!tile_can_walk(map->tiles[map->x*(self->y-i)+self->x])) break; victim=get_spawn_at(self->x, self->y-i, map); if(victim!=NULL){ /*weniger bei mehr Entfernung*/ damage=(11-i)*3; break; } } break; case SOUTH: for(unsigned int i=1;i<=10 && self->y+i<map->y;i++){ /*wenn da ne Wand ist, nichts tun*/ if(!tile_can_walk(map->tiles[map->x*(self->y+i)+self->x])) break; victim=get_spawn_at(self->x, self->y+i, map); if(victim!=NULL){ damage=(11-i)*3; break; } } break; case WEST: for(unsigned int i=1;i<=10 && self->x-i+1;i++){ /*wenn da ne Wand ist, nichts tun*/ if(!tile_can_walk(map->tiles[map->x*self->y+self->x-i])) break; victim=get_spawn_at(self->x-i, self->y, map); if(victim!=NULL){ damage=(11-i)*3; break; } } break; case EAST: for(unsigned int i=1;i<=10 && self->x+i<map->x;i++){ /*wenn da ne Wand ist, nichts tun*/ if(!tile_can_walk(map->tiles[map->x*self->y+self->x+i])) break; victim=get_spawn_at(self->x+i, self->y, map); if(victim!=NULL){ damage=(11-i)*3; break; } } break; default: break; } if(victim!=NULL) damage_spawn(victim, damage, map); } else push_msg("Keine Munition mehr!", map); break; default: break; } }