/* SETUP starts a new control request. Devices are not allowed to * STALL or NAK these; they must cancel any pending control requests. */ static void setup_packet( struct sl811 *sl811, struct sl811h_ep *ep, struct urb *urb, u8 bank, u8 control ) { u8 addr; u8 len; void __iomem *data_reg; addr = SL811HS_PACKET_BUF(bank == 0); len = sizeof(struct usb_ctrlrequest); data_reg = sl811->data_reg; sl811_write_buf(sl811, addr, urb->setup_packet, len); /* autoincrementing */ sl811_write(sl811, bank + SL11H_BUFADDRREG, addr); writeb(len, data_reg); writeb(SL_SETUP /* | ep->epnum */, data_reg); writeb(usb_pipedevice(urb->pipe), data_reg); /* always OUT/data0 */ ; sl811_write(sl811, bank + SL11H_HOSTCTLREG, control | SL11H_HCTLMASK_OUT); ep->length = 0; PACKET("SETUP qh%p\n", ep); }
/* STATUS finishes control requests, often after IN or OUT data packets */ static void status_packet( struct sl811 *sl811, struct sl811h_ep *ep, struct urb *urb, u8 bank, u8 control ) { int do_out; void __iomem *data_reg; do_out = urb->transfer_buffer_length && usb_pipein(urb->pipe); data_reg = sl811->data_reg; /* autoincrementing */ sl811_write(sl811, bank + SL11H_BUFADDRREG, 0); writeb(0, data_reg); writeb((do_out ? SL_OUT : SL_IN) /* | ep->epnum */, data_reg); writeb(usb_pipedevice(urb->pipe), data_reg); /* always data1; sometimes IN */ control |= SL11H_HCTLMASK_TOGGLE; if (do_out) control |= SL11H_HCTLMASK_OUT; sl811_write(sl811, bank + SL11H_HOSTCTLREG, control); ep->length = 0; PACKET("STATUS%s/%s qh%p\n", ep->nak_count ? "/retry" : "", do_out ? "out" : "in", ep); }
/* IN packets can be used with any type of endpoint. here we just * start the transfer, data from the peripheral may arrive later. * urb->iso_frame_desc is currently ignored here... */ static void in_packet( struct sl811 *sl811, struct sl811h_ep *ep, struct urb *urb, u8 bank, u8 control ) { u8 addr; u8 len; void __iomem *data_reg; /* avoid losing data on overflow */ len = ep->maxpacket; addr = SL811HS_PACKET_BUF(bank == 0); if (!(control & SL11H_HCTLMASK_ISOCH) && usb_gettoggle(urb->dev, ep->epnum, 0)) control |= SL11H_HCTLMASK_TOGGLE; data_reg = sl811->data_reg; /* autoincrementing */ sl811_write(sl811, bank + SL11H_BUFADDRREG, addr); writeb(len, data_reg); writeb(SL_IN | ep->epnum, data_reg); writeb(usb_pipedevice(urb->pipe), data_reg); sl811_write(sl811, bank + SL11H_HOSTCTLREG, control); ep->length = min((int)len, urb->transfer_buffer_length - urb->actual_length); PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len); }
void g1_server_class::start_game() { PACKET(packet,r); r.write_8(G1_PK_WE_ARE_STARTING); r.write_32(4); send_to_all(packet,&r); send_to_all(packet,&r); state=LOADING; };
void AppServer::sendTest(std::string msg) { PACKET(PacketTest, PACKET_TEST); #ifdef PACKET_WITH_JSON std::string data = "{\"msg\":" + msg + "}"; packet->setData(data, 0, false); #else packet->msg = msg; #endif SEND_PACKET(packet) }
int g1_client_class::prepare_command(int command) { g1_global_id.poll(); switch (state) { case SYNCING: case LOADING: { state=SYNCING; PACKET(sp,r); r.write_8(G1_PK_LOADING_DONE); i4_warning("We are ready to start."); send_server(sp,&r); } return NE_ERROR_NOTREADY; case RUNNING: { if (!network_file) { network_file=new i4_temp_file_class(2000,2000); } switch (command) { case G1_PK_GAME_DATA: { network_file->clear(); network_file->write_8(command); network_file->write_32(0); //placeholder for length network_file->write_32(g1_tick_counter); } break; case G1_PK_PROCESS: { send_server(network_file->get_buffer(),network_file); network_file->clear(); network_file->write_8(G1_PK_GAME_DATA); network_file->write_32(0); network_file->write_32(g1_tick_counter); } break; } } break; } if (!g1_global_id.is_ready()) { return NE_ERROR_NOTREADY; } return NE_ERROR_OK; }
CNpc::CNpc(uint8_t *pData, uint32_t size) { PACKET(Packets::SSpawnNPCPacket::SPacket, pData, packet); m_Object.dir = TO_FLOAT_DIR(packet.dir); m_Object.id = packet.id; m_Object.type = packet.type; m_Object.x = packet.x; m_Object.y = packet.y; m_Object.z = packet.z; m_Object.dead = false; }
static int crt_image_findfile(crt_image *image, const char *fname) { int nr=0; char name[6]; int i=sizeof(crt_header); while (i<image->size) { sprintf(name, "%d",nr); if (!strcmp(fname, name) ) return i; i+=GET_ULONG( PACKET(image, i)->packet_length ); nr++; } return 0; }
CPlayer::CPlayer(uint8_t *pData, uint32_t size) { PACKET(Packets::SSpawnPlayerPacket::SPacket, pData, packet); m_Object.dir = TO_FLOAT_DIR(packet.dir); m_Object.id = packet.id; m_Object.type = packet.type; m_Object.x = packet.x; m_Object.y = packet.y; m_Object.z = packet.z; m_Object.dead = packet.dead == 0 ? false : true; m_Player.state = packet.state; }
static int crt_image_readfile(imgtool_image *img, const char *fname, imgtool_stream *destf) { crt_image *image=(crt_image*)img; int size; int pos; if (!(pos=crt_image_findfile(image, fname)) ) return IMGTOOLERR_MODULENOTFOUND; size=GET_UWORD( PACKET(image, pos)->length ); if (stream_write(destf, image->data+pos+sizeof(crt_packet), size)!=size) { return IMGTOOLERR_WRITEERROR; } return 0; }
// app data -> SSL -> protocol encapsulation -> reliability layer -> network void down_stack_app() { if (ssl_started_) { // push app-layer cleartext through SSL object while (!app_write_queue.empty()) { BufferPtr& buf = app_write_queue.front(); try { const ssize_t size = ssl_->write_cleartext_unbuffered(buf->data(), buf->size()); if (size == SSLContext::SSL::SHOULD_RETRY) break; } catch (...) { if (stats) stats->error(Error::SSL_ERROR); invalidate(Error::SSL_ERROR); throw; } app_write_queue.pop_front(); } // encapsulate SSL ciphertext packets while (ssl_->read_ciphertext_ready() && rel_send.ready()) { typename ReliableSend::Message& m = rel_send.send(*now); m.packet = PACKET(ssl_->read_ciphertext()); // encapsulate packet try { encapsulate(m.id(), m.packet); } catch (...) { if (stats) stats->error(Error::ENCAPSULATION_ERROR); invalidate(Error::ENCAPSULATION_ERROR); throw; } // transmit it net_send(m.packet, NET_SEND_SSL); } } }
static int crt_image_deletefile(imgtool_image *img, const char *fname) { crt_image *image=(crt_image*)img; int size; int pos; if (!(pos=crt_image_findfile(image, fname)) ) { return IMGTOOLERR_MODULENOTFOUND; } size=GET_ULONG(PACKET(image, pos)->packet_length); if (image->size-pos-size>0) memmove(image->data+pos, image->data+pos+size, image->size-pos-size); image->size-=size; image->modified=1; return 0; }
/* OUT packets can be used with any type of endpoint. * urb->iso_frame_desc is currently ignored here... */ static void out_packet( struct sl811 *sl811, struct sl811h_ep *ep, struct urb *urb, u8 bank, u8 control ) { void *buf; u8 addr; u8 len; void __iomem *data_reg; buf = urb->transfer_buffer + urb->actual_length; prefetch(buf); len = min((int)ep->maxpacket, urb->transfer_buffer_length - urb->actual_length); if (!(control & SL11H_HCTLMASK_ISOCH) && usb_gettoggle(urb->dev, ep->epnum, 1)) control |= SL11H_HCTLMASK_TOGGLE; addr = SL811HS_PACKET_BUF(bank == 0); data_reg = sl811->data_reg; sl811_write_buf(sl811, addr, buf, len); /* autoincrementing */ sl811_write(sl811, bank + SL11H_BUFADDRREG, addr); writeb(len, data_reg); writeb(SL_OUT | ep->epnum, data_reg); writeb(usb_pipedevice(urb->pipe), data_reg); sl811_write(sl811, bank + SL11H_HOSTCTLREG, control | SL11H_HCTLMASK_OUT); ep->length = len; PACKET("OUT%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", !!usb_gettoggle(urb->dev, ep->epnum, 1), ep, len); }
static int crt_image_writefile(imgtool_image *img, const char *fname, imgtool_stream *sourcef, const ResolvedOption *_options) { crt_image *image=(crt_image*)img; int size; int pos; size=stream_size(sourcef); if (!(pos=crt_image_findfile(image, fname)) ) { // appending pos=image->size; if (!(image->data=realloc(image->data, image->size+size+sizeof(crt_packet))) ) return IMGTOOLERR_OUTOFMEMORY; image->size+=size+sizeof(crt_packet); } else { int oldsize=GET_ULONG(PACKET(image,pos)->packet_length); // overwritting if (!(image->data=realloc(image->data, image->size+size+sizeof(crt_packet)-oldsize) ) ) return IMGTOOLERR_OUTOFMEMORY; if (image->size-pos-oldsize!=0) { memmove(image->data+pos+size+sizeof(crt_packet), image->data+pos+oldsize, image->size-pos-oldsize); } image->size+=size+sizeof(crt_packet)-oldsize; } if (stream_read(sourcef, image->data+pos+sizeof(crt_packet), size)!=size) { return IMGTOOLERR_READERROR; } memset(image->data+pos, 0, sizeof(crt_packet)); memcpy(PACKET(image,pos)->id,"CHIP",4); SET_ULONG( PACKET(image, pos)->packet_length, size+sizeof(crt_packet)); SET_UWORD(PACKET(image, pos)->chip_type, _options[C64CRT_FILEOPTION_FTYPE].i); SET_UWORD( PACKET(image, pos)->address, _options[C64CRT_FILEOPTION_FADDR].i); SET_UWORD( PACKET(image, pos)->bank, _options[C64CRT_FILEOPTION_FBANK].i); SET_UWORD( PACKET(image, pos)->length, size); image->modified=1; return 0; }
static int crt_image_nextenum(imgtool_directory *enumeration, imgtool_dirent *ent) { crt_iterator *iter=(crt_iterator*)enumeration; ent->corrupt=0; if (!(ent->eof=(iter->pos>=iter->image->size))) { sprintf(ent->fname,"%d", iter->number); ent->filesize=GET_UWORD( PACKET(iter->image, iter->pos)->length ); if (ent->attr) { unsigned crc=crc32(0, iter->image->data+iter->pos+sizeof(crt_packet), ent->filesize); sprintf(ent->attr,"%-4s %s bank:%-2d addr:%.4x crc:%8x", (char*)PACKET(iter->image, iter->pos), chip_types[GET_UWORD(PACKET(iter->image,iter->pos)->chip_type)], GET_UWORD( PACKET(iter->image,iter->pos)->bank), GET_UWORD( PACKET(iter->image,iter->pos)->address), crc); } iter->number++; iter->pos+=GET_ULONG( PACKET(iter->image, iter->pos)->packet_length ); } return 0; }
void g1_server_class::process_client_packet(w8 * packet, int packet_length, int client_num) { clients[client_num].last_data.get(); i4_ram_file_class r(packet, packet_length); w8 msg=r.read_8(); switch (msg) { case G1_PK_I_WANNA_JOIN: { r.read_16(); // skip use port delete clients[client_num].username; clients[client_num].username=r.read_counted_str(); send_player_joined(client_num); } break; case G1_PK_LOADING_DONE: { clients[client_num].flags|=READY; i4_bool ok=i4_T; for (int i=0; i<G1_MAX_PLAYERS; i++) { if (clients[i].addr && !(clients[i].flags&READY)) { ok=i4_F; //at least one is not yet ready; } } if (ok&&state==SYNCING) { int rem_players,player,k,k2; rem_players=0; player=1; //zero is always neutral, //1 is usually local (server) player if (player==local_player_num) { player++; } for(k=0; k<G1_MAX_PLAYERS; k++) { if (clients[k].addr!=0) { rem_players++; clients[k].remote_player_num=player; player++; if (player==local_player_num) { player++; } } } for (player=0; player<G1_MAX_PLAYERS; player++) { if (clients[player].addr) { PACKET(sp,s); s.write_8(G1_PK_GAME_START); s.write_32(G1_MAX_PLAYERS); //So many ai's are going to follow for (k=0; k<G1_MAX_PLAYERS; k++) { s.write_32(k); g1_player_info_class * pl=g1_player_man.get(k); i4_bool found=i4_F; if (k==0) //the neutral player { s.write_counted_str(*(pl->get_ai()->ai_name())); found=i4_T; } else if (k==local_player_num) { s.write_counted_str("remote_player"); found=i4_T; } else { for (k2=0; k2<G1_MAX_PLAYERS; k2++) { if (clients[k2].addr && clients[k2].remote_player_num==k) { //this automatically indicates //that it is the remote local player //(only one player can be human at a time on //a particular machine) s.write_counted_str("human"); found=i4_T; break; } } } if (!found) //this player will stay the same as originally defined on the map { s.write_counted_str(*(pl->get_ai()->ai_name())); found=i4_T; } } send_to(sp,&s,player); send_to(sp,&s,player); //its important! } } //finally, set the matching ai's also for the server for (player=0; player<G1_MAX_PLAYERS; player++) { g1_team_api_class * newai=0; i4_bool found=i4_F; if (player==0) { newai=g1_create_ai("ai_neutral",0); g1_player_man.get(player)->set_ai(newai); newai->init(); found=i4_T; } else if (player==local_player_num) { newai=g1_create_ai("human",0); g1_player_man.get(player)->set_ai(newai); newai->init(); g1_player_man.local_player=player; found=i4_T; } else { for (k2=0; k2<G1_MAX_PLAYERS; k2++) { if (clients[k2].addr && clients[k2].remote_player_num==player) { //player "player" is a remote player newai=g1_create_ai("remote_player"); g1_player_man.get(player)->set_ai(newai); newai->init(); found=i4_T; } } } //in all other cases, we read the correct ai from the disk } g1_global_id.enable_networking(ID_NET_SERVER); state=RUNNING; i4_warning("Server: Switched to running state."); } } break; case G1_PK_GAME_DATA: { process_data_packet(r,i4_T); /* r.read_32();//skip empty field w32 ticksent=r.read_32();//to which tick does this packet belong? //here follows: reading out the objects g1_realtime_loader_class *rtloader=new g1_realtime_loader_class(&r,i4_F,i4_F); w32 objfor=rtloader->read_32(); w16 typefor=0; while (objfor!=0) { if (objfor==g1_global_id_manager_class::ID_DELETEPROPAGATE) { //don't delete if object just doesn't exist locally. objfor=rtloader->read_32(); g1_object_class *obdel=g1_global_id.checked_get(objfor); if (obdel) { obdel->set_flag(g1_object_class::THINKING,1);//Perhaps was not thinking locally obdel->stop_thinking(); obdel->unoccupy_location(); obdel->request_remove(); } } else { typefor=rtloader->read_16(); g1_object_class *obj=g1_global_id.checked_get(objfor); if (!obj) { //Object seems to be new //obj=g1_create_object(typefor); if (typefor>=0 && typefor<=g1_last_object_type) { //The object will just be in sync obj=g1_object_type_array[typefor]->create_object(typefor,rtloader); obj->occupy_location(); obj->grab_old(); if (obj->get_flag(g1_object_class::THINKING)) obj->request_think(); g1_player_man.get(obj->player_num)->add_object(obj->global_id); } else { i4_error("ERROR: Unknown object type requested"); delete rtloader; return; } //g1_global_id.assign(objfor,obj); } else { obj->load(rtloader); } obj->set_flag(g1_object_class::NEEDS_SYNC,1); } objfor=rtloader->read_32(); } //don't forget to mark these as to be resent. delete rtloader; */ } break; default: { if (msg>=G1_PK_ID_BASE && msg<=G1_PK_ID_END) { r.seek(0); g1_global_id.receive_packet(&r); } } } }
i4_bool g1_client_class::poll() // returns false if server is not responding { if (!listen || !send) { return 0; } if (state==JOIN_START) { i4_time_class now; if (now.milli_diff(last_responce_time)>40000) // if it's been 40 secs assume server dead { i4_message_box("Server not responding","The server is not responding any more. ",MSG_OK); return i4_F; } w8 packet[512]; i4_ram_file_class r(packet, sizeof(packet)); r.write_8(G1_PK_I_WANNA_JOIN); r.write_16(use_port); r.write_counted_str(*g1_resources.username); if (!send->write(packet, r.tell())) { return i4_F; } } if (state==SYNCING) //set from the main loop as soon as the map is loaded { PACKET(pack,fp); //we just resend this message till we get the matching reply fp.write_8(G1_PK_LOADING_DONE); send_server(pack,&fp); } int noloops=0; while (listen->ready_to_read() && noloops<10) { w8 packet[MAX_PACKET_SIZE]; i4_net_address * a; int s=listen->read_from(packet, sizeof(packet), a); if (a->equals(server_address)) { i4_ram_file_class r(packet, sizeof(packet)); w8 new_message=r.read_8(); switch (new_message) { case G1_PK_YOU_HAVE_JOINED: { player_num=(w8)r.read_16(); if (map_name) { delete map_name; } map_name=r.read_counted_str(); i4_warning("We were accepted by the server to join"); state=CONNECTING; last_responce_time.get(); } break; case G1_PK_WE_ARE_STARTING: { num_players=r.read_32(); if (state==CONNECTING) { i4_warning("Loading game data"); //don't do this twice. //i4_user_message_event_class u(G1_START_NEW_GAME); i4_file_open_message_class u(G1_SAVEGAME_LOAD_OK, new i4_str (* map_name)); i4_kernel.send_event(i4_current_app, &u); state=LOADING; } //li_call("hide_main_menu"); } break; case G1_PK_GAME_START: { //from now on, it's the main loops task to know that //this is a net game if (state!=RUNNING) { int num_ais=r.read_32(); if (num_ais>G1_MAX_PLAYERS) { i4_error("ERROR: Local Golgotha version supports fewer players than this game needs. Check your version."); num_ais=G1_MAX_PLAYERS; } i4_str * ainame=0; g1_team_api_class * newai=0; for (int ais=0; ais<num_ais; ais++) { //the player the next ai is for w32 aifor=r.read_32(); ainame=r.read_counted_str(); char buf[100]; i4_os_string(*ainame,buf,100); newai=g1_create_ai(buf,0); if (strcmp(buf,"human")==0) { //this will be the local player g1_player_man.local_player=ais; i4_warning("We were assigned player number %i.",ais); } g1_player_man.get(ais)->set_ai(newai); newai->init(); delete ainame; } g1_global_id.enable_networking(ID_NET_CLIENT); state=RUNNING; i4_warning("The game is in sync and has started"); } //this message is sent by the server if all clients are ready } break; case G1_PK_GAME_DATA: { process_data_packet(r,i4_F); } break; default: { if (new_message>=G1_PK_ID_BASE && new_message<=G1_PK_ID_END) { r.seek(0); g1_global_id.receive_packet(&r); } } } } delete a; noloops++; } return i4_T; }
void AppServer::sendHeartBeat(void * data) { PACKET(PacketHBeat, PACKET_HEARTBEAT); SEND_PACKET(packet) }
void ProcessUDP(Socket *s, socket_t client, void *buf, size_t len) { if (len > 512) { printf("WARNING: Invalid packet size: %ld, rejecting packet.\n", len); return; } #ifdef _DEBUG printf("============= PACKET DATA ==========\n"); fwrite(buf, 1, len, stdout); printf("\nHex:\n"); for (size_t i = 0, j = 0; i < len; ++i, j++) { j %= 11; printf("%-3X%c", ((uint8_t*)buf)[i], j == 10 ? '\n' : '\0'); } tfm::printf("\nPacket Type: %s", PACKET(*(uint8_t*)buf)); printf("\n============= END PACKET DATA ==========\n"); #endif for (auto it = clients.begin(), it_end = clients.end(); it != it_end;) { printf("Iterating client!\n"); whatever_t *w = *it; if (w->c.in.sin_port == client.in.sin_port) { printf("Found client!\n"); packet_t pak; memset(&pak, 0, sizeof(packet_t)); // Copy the packet. memcpy(&pak, buf, len); #ifdef _DEBUG tfm::printf("RAW: packet %d (%.8X), packetno: %d (%.8X)\n", pak.packet, pak.packet, pak.packetno, pak.packetno); tfm::printf("RAW ENDIAN: packet %d (%.8X), packetno: %d (%.8X)\n", pak.packet, pak.packet, htonl(pak.packetno), htonl(pak.packetno)); tfm::printf("Received packet %d (%s)\n", pak.packet, PACKET(pak.packet)); #endif // So it isnt a burst, but are we bursting? if (!w->bursting) { tfm::printf("Received packet %d (%s) but we're not bursting?? ignoring packet.\n", pak.packet, PACKET(pak.packet)); return; } /* * Description: * So basically the way this works is that we have 5 types of UDP packets. * The first packet type is a "DATABURST" packet, signalling that the client wants to initiate a databurst. * The second packet consists of a timeout value which is uint32_t bytes long, this is the time the client expects to reply. * The third packet type is the number of packet chunks that will be sent (number of datablocks to expect). * The forth packet type is the actual data info from the client which is MessagePack data. * The fifth packet type signals the end of the databurst and to terminate the connection. */ switch (pak.packet) { case TIMEOUT: // unfuck ntohl. w->timeout = pak.packetno;//ntohl(pak.packetno); return; case INFOPACKS: w->totalpackets = pak.packetno;//ntohl(pak.packetno); return; case INFO: { // TODO: Prevent buffer-overrun attack? size_t datalen = len - sizeof(uint8_t) - sizeof(uint32_t); uint8_t *typeddata = reinterpret_cast<uint8_t*>(pak.data); w->data.insert(w->data.end(), typeddata, typeddata + datalen); w->receivedpackets++; return; } case ENDBURST: { if (w->receivedpackets == w->totalpackets) { printf("Processing client."); break; // continue running the function. } else { // Just delete the received packets and continue until next response. printf("Received invalid number of data packets: %ld (expected %ld)\n", w->receivedpackets, w->totalpackets); clients.erase(it); delete w; return; } } default: printf("Invalid packet %d, rejecting...\n", pak.packet); return; } printf("Received data burst! Unserializing the data...\n"); // Unserialize the packet data, then process. information_t *info = UnserializeData(w->data); // Process the info structure, this submits it to the database among other things. tfm::printf("Updating databases and processing information for %s, next timeout at %d\n", info->Hostname, w->timeout); ProcessInformation(info, w->timeout); // Remove ourselves from the vector. clients.erase(it); delete w; printf("Finised!\n"); return; } ++it; } // We're starting a new client. whatever_t *we = new whatever_t; memset(we, 0, sizeof(whatever_t)); memcpy(&we->c, &client, sizeof(socket_t)); // Is this the start of a burst? if (*(uint8_t*)buf == DATABURST) we->bursting = true; clients.push_back(we); }
{ uint32_t *handles = cl + offset; fprintf(stderr, "0x%08x 0x%08x: handle 0: %d, handle 1: %d\n", offset, hw_offset, handles[0], handles[1]); } #define PACKET_DUMP(name) [name] = { #name, name ## _SIZE, dump_##name } #define PACKET(name) [name] = { #name, name ## _SIZE, NULL } static const struct packet_info { const char *name; uint8_t size; void (*dump_func)(void *cl, uint32_t offset, uint32_t hw_offset); } packet_info[] = { PACKET(VC4_PACKET_HALT), PACKET(VC4_PACKET_NOP), PACKET(VC4_PACKET_FLUSH), PACKET(VC4_PACKET_FLUSH_ALL), PACKET(VC4_PACKET_START_TILE_BINNING), PACKET(VC4_PACKET_INCREMENT_SEMAPHORE), PACKET(VC4_PACKET_WAIT_ON_SEMAPHORE), PACKET(VC4_PACKET_BRANCH), PACKET_DUMP(VC4_PACKET_BRANCH_TO_SUB_LIST), PACKET(VC4_PACKET_STORE_MS_TILE_BUFFER), PACKET(VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF), PACKET_DUMP(VC4_PACKET_STORE_FULL_RES_TILE_BUFFER), PACKET_DUMP(VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER),
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "util/u_math.h" #include "util/macros.h" #include "vc4_context.h" #define PACKET(name, size) [name] = { #name, size } static const struct packet_info { const char *name; uint8_t size; } packet_info[] = { PACKET(VC4_PACKET_HALT, 1), PACKET(VC4_PACKET_NOP, 1), PACKET(VC4_PACKET_FLUSH, 1), PACKET(VC4_PACKET_FLUSH_ALL, 1), PACKET(VC4_PACKET_START_TILE_BINNING, 1), PACKET(VC4_PACKET_INCREMENT_SEMAPHORE, 1), PACKET(VC4_PACKET_WAIT_ON_SEMAPHORE, 1), PACKET(VC4_PACKET_BRANCH, 5), PACKET(VC4_PACKET_BRANCH_TO_SUB_LIST, 5), PACKET(VC4_PACKET_STORE_MS_TILE_BUFFER, 1), PACKET(VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF, 1), PACKET(VC4_PACKET_STORE_FULL_RES_TILE_BUFFER, 5), PACKET(VC4_PACKET_LOAD_FULL_RES_TILE_BUFFER, 5),
void g1_server_class::poll() { int i,noloops=0; list_changed=i4_F; while (udp_port && udp_port->ready_to_read() && noloops<10) { w8 packet[MAX_PACKET_SIZE]; i4_net_address * a; int len=udp_port->read_from(packet, sizeof(packet), a); // see if this was from one of our clients int found=0, free_spot=-1; for (i=0; i<G1_MAX_PLAYERS; i++) { if (clients[i].addr) { if (clients[i].addr->equals(a)) { process_client_packet(packet, len, i); found=1; } } else { free_spot=i; break; } } if (!found && free_spot!=-1) { i4_ram_file_class r(packet, len); if (r.read_8()==G1_PK_I_WANNA_JOIN) { clients[free_spot].addr=a->copy(); clients[free_spot].addr->set_port(r.read_16()); clients[free_spot].username=r.read_counted_str(); clients[free_spot].send=protocol->connect(clients[free_spot].addr, I4_PACKETED_DATA); clients[free_spot].last_data.get(); if (clients[free_spot].send) { send_player_joined(free_spot); } else { clients[free_spot].cleanup(); } list_changed=i4_T; } } delete a; noloops++; } if (state==WAITING_FOR_PLAYERS) { i4_time_class now; for (i=0; i<G1_MAX_PLAYERS; i++) { if (clients[i].addr && now.milli_diff(clients[i].last_data)>50000) { clients[i].cleanup(); list_changed=i4_T; } } } if (state==LOADING) //has this guy lost a message? { i4_time_class now; for (i=0; i<G1_MAX_PLAYERS; i++) { if (clients[i].addr && now.milli_diff(clients[i].last_data)>30000) { PACKET(rp,rpf); rpf.write_8(G1_PK_WE_ARE_STARTING); rpf.write_32(4); send_to(rp,&rpf,i); } } } }