Index: Daodan/MSVC/Daodan_BSL.c
===================================================================
--- Daodan/MSVC/Daodan_BSL.c	(revision 567)
+++ Daodan/MSVC/Daodan_BSL.c	(revision 568)
@@ -475,6 +475,6 @@
 	else index = args[0].value_int32;
 
-	Chr = ONgGameState->CharacterStorage;
-	Active = ONrGetActiveCharacter(&Chr[index]);
+	Chr = &(ONgGameState->CharacterStorage[index]);
+	Active = ONrGetActiveCharacter(Chr);
 	if (!Active) return 1;
 
@@ -819,4 +819,5 @@
 	SLrScript_Command_Register_ReturnType("d_maxhealth","Gets or sets a character's maximum health", "[ai_name:string | script_id:int] [newmaxhealth:int] [scalehealth:bool]", sl_str32, bsl_maxhealth);
 	SLrScript_Command_Register_ReturnType("d_powerup","Gets or sets a character's powerups", "[ai_name:string | script_id:int] powerup:string", sl_int32, bsl_powerup);
+	//d_holdkey is broken!
 	SLrScript_Command_Register_ReturnType("d_holdkey","Makes a character hold a key", "[ai_name:string | script_id:int] frames:int keys:string", sl_int32, bsl_holdkey);
 	SLrScript_Command_Register_ReturnType("d_isheld","Checks if player is holding a key", "[ai_name:string | script_id:int] [keys:string]", sl_int32, bsl_isheld);
Index: Daodan/MSVC/Flatline.c
===================================================================
--- Daodan/MSVC/Flatline.c	(revision 567)
+++ Daodan/MSVC/Flatline.c	(revision 568)
@@ -15,4 +15,28 @@
 };
 
+#define BETTER_SYNC
+
+void DoRareSync( short Player, sockaddr_in * sender )
+{
+	flatline_packet sync = {0};	
+
+	if (Player > max_connections || !PlayerList[ Player ] ) return;
+	
+			
+//	DDrConsole_PrintF( "Sending sync data for player %i, new index %u", Player, PlayerList[ Player ]->rare_sync_index);
+	sender->sin_addr.S_un.S_addr = htonl(sender->sin_addr.S_un.S_addr);
+	sync.id = RARE_SYNC_DATA;
+	sprintf( sync.rare_sync_data.Class, TMrInstance_GetInstanceName( PlayerList[ Player ]->Chr->ONCC ) );
+	//using ->Inventory instead of ->Chr->Inventory to keep the index and Inventory in sync, just in case.
+	memcpy( &(sync.rare_sync_data.Inventory), &(PlayerList[ Player ]->Inventory), sizeof(Inventory) );
+	//WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
+	sync.rare_sync_data.Inventory.Weapons[0] = NULL;
+	sync.rare_sync_data.Inventory.Weapons[1] = NULL;
+	sync.rare_sync_data.Inventory.Weapons[2] = NULL;
+	sync.rare_sync_data.PlayerNum = Player;
+	sync.rare_sync_data.index = PlayerList[ Player ]->rare_sync_index;
+	NetTCPServer_Send( sender, (char*)&sync, sizeof(rare_sync_data) + FLATLINE_HEADER );
+}
+
 bool FLrServer_PacketCallback(char* data, int datalen, int from)
 {
@@ -72,5 +96,5 @@
 				memset(Char, 0, sizeof(CharacterObject));
 				Char->Header.Type = 'CHAR';
-				Char->OSD.Options = chr_dontaim | chr_unkillable;
+				Char->OSD.Options = chr_dontaim;
 				for(j = 0; j < max_connections; j++) {
 					if(PlayerList[j] != 0) {
@@ -170,8 +194,11 @@
 				PlayerList[i]->MouseDeltaX = packet_input->MouseDeltaX;
 				PlayerList[i]->MouseDeltaY = packet_input->MouseDeltaY;
-
+				PlayerList[i]->LastInputTime = packet_input->Time;
 
 				break;
 			}
+		case RARE_SYNC_DATA_REQUEST:
+			DoRareSync( packet->sync_request , &sender);
+			break;
 		default:
 			DDrConsole_PrintF("Warning, recieved badly formed packet!");
@@ -226,11 +253,13 @@
 
 					client_slot = ((connect_reply*)packet->data)->player_slot;
+
+					PlayerList[client_slot] = Players+client_slot;
+					PlayerList[client_slot]->Chr = ONgGameState->PlayerCharacter;
+
+					DDrConsole_PrintColored("Connection successful!",0,green, grey);
 					
-			PlayerList[client_slot] = Players+client_slot;
-			PlayerList[client_slot]->Chr = ONgGameState->PlayerCharacter;
-			
-			
-
-					DDrConsole_PrintColored("Connection successful!",0,green, grey);
+					//disable local input.
+					DDrPatch_NOOP(0x004FA929, 5 + 6 + 5);
+					
 					//DDrConsole_PrintF("Slot %i",  ((connect_reply*)packet)->player_slot);
 					break;
@@ -322,7 +351,9 @@
 			else {
 				ONrGameState_NewCharacter(Char, NULL, NULL, &chr_index);
+				ONgGameState->CharacterStorage[chr_index].field_1E8 = 0;
 				PlayerList[packet.new_player.Playernumber] = &Players[chr_index];
 				Players[chr_index].Chr = &(ONgGameState->CharacterStorage[chr_index]);
 				Players[chr_index].Chr->Flags &= 0xFFBFFFFF;
+				Players[chr_index].spawnnumber = chr_index;
 				DDrConsole_PrintF("Spawning player %s, class %s, slot  %i", ((new_player*)(packet.data))->Character.OSD.Name, ((new_player*)(packet.data))->Character.OSD.Class,chr_index) ;
 			}
@@ -341,5 +372,5 @@
 			if( !PlayerList[i] ) break;
 			//PlayerList[i]->Chr = ((GameState *)ONgGameState)->CharacterStorage;
-			
+#ifndef BETTER_SYNC
 			PlayerList[i]->Chr->Health = data->Health;
 			PlayerList[i]->Chr->MaxHealth = data->MaxHealth;
@@ -359,4 +390,21 @@
 
 			Active->PhyContext->Position = data->Position;
+#else
+			PlayerList[i]->Actions1 = data->Inputs.Actions1;
+			PlayerList[i]->Actions2 = data->Inputs.Actions2;
+			PlayerList[i]->MouseDeltaX = data->Inputs.MouseDeltaX;
+			PlayerList[i]->MouseDeltaY = data->Inputs.MouseDeltaY;
+			memcpy( &(PlayerList[i]->player_data), data, sizeof(player_data) );
+#endif
+			if( !server_started && data->rare_sync_index > PlayerList[i]->rare_sync_index )
+			{
+					int sent_bytes;
+					flatline_packet sync_request = {0};
+					sync_request.id = RARE_SYNC_DATA_REQUEST;
+					sync_request.sync_request = i;
+					DDrConsole_PrintF( "Requesting sync data for player %i, old index %u", i, PlayerList[i]->rare_sync_index);
+					sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&sync_request, FLATLINE_HEADER + sizeof(int) );
+			}
+
 
 #if 0		
@@ -389,4 +437,38 @@
 			break;
 			}
+		case RARE_SYNC_DATA:
+			if(1) {
+			sl_arg hax[2];
+			int dontuse;
+			uint16_t i = packet.rare_sync_data.PlayerNum;
+						
+			if (i > max_connections) break;
+			if( !PlayerList[i] ) break;
+
+			//WEAPONS ARE DISABLED. Why? Pain in the arse to sync.
+			packet.rare_sync_data.Inventory.Weapons[0] = NULL;
+			packet.rare_sync_data.Inventory.Weapons[1] = NULL;
+			packet.rare_sync_data.Inventory.Weapons[2] = NULL;
+//			TMrInstance_GetDataPtr( 'ONCC', packet.rare_sync_data.Class, PlayerList[ i ]->Chr->ONCC );
+			
+			//add the target character
+			hax[0].type = sl_int32;
+			hax[0].value_int32 = PlayerList[ packet.rare_sync_data.PlayerNum ]->spawnnumber;
+
+			//add the new class
+			//fix this later so we cant buffer overflow :O
+			hax[1].type = sl_str32;
+			hax[1].value_str32 = packet.rare_sync_data.Class;
+			
+			//we are directly calling a bsl function instead of using the normal method for two reasons
+			//1. it has all the checking built in
+			iSetCharacterClass( 0, 2, hax, &dontuse, &dontuse, hax );
+			//DDrConsole_PrintF( "Recieved sync data for player %i, class %s, old index %u, new index %u", i, packet.rare_sync_data.Class, PlayerList[i]->rare_sync_index, packet.rare_sync_data.index);
+			memcpy( &(PlayerList[ i ]->Chr->Inventory), &(packet.rare_sync_data.Inventory), sizeof(Inventory ));
+
+			PlayerList[i]->rare_sync_index = packet.rare_sync_data.index;
+			}
+			break;
+			
 		default:
 			DDrConsole_PrintF("Warning, recieved badly formed packet!");
@@ -402,27 +484,5 @@
 }
 
-//UDPServer_SendToAll
-//Sends a packet to all the clients currently connected.
-//Returns the number of players sent to.
-int UDPServer_SendToAll(void* packet, int size) {
-	int j;
-	int players = 0;
-	sockaddr_in address;
-	memset(&address, 0, sizeof(sockaddr_in)); 
-	address.sin_family = AF_INET;
-	address.sin_addr.s_addr = htonl(INADDR_ANY);
-	address.sin_port = htons(27777);
-	for(j = 0; j < max_connections; j++) {
-		if (PlayerList[j] != 0 && PlayerList[j]->ip && (PlayerList[j]->ip != inet_addr("127.0.0.1"))) {
-			int sent_bytes;
-			address.sin_addr.s_addr = htonl(PlayerList[j]->ip);//*((struct in_addr*)(int*)&(Players[j].ip));		
-			sent_bytes = NetUDPServer_Send((sockaddr *) &address, (char*)packet, size);
-			if(sent_bytes == SOCKET_ERROR) NetCatchError();
-			else players++;
-		}
-	}
-	return players;
-}
-
+//wtf, this needs cleaned up...
 player_info *FLr_FindEmptySlot() {
 	int j;
@@ -450,5 +510,21 @@
 void * ONICALL FLrInput_Update_Keys(void) 
 {
-		uint16_t i;
+	uint16_t i;
+	/*DDrConsole_PrintF("Current: %x %x | Start: %x %x | Stop: %x %x | Stopped %x %x", 
+		ONgGameState->Input.Current.Actions1, ONgGameState->Input.Current.Actions2,
+		ONgGameState->Input.Start.Actions1,ONgGameState->Input.Start.Actions2,
+		ONgGameState->Input.Stop.Actions1, ONgGameState->Input.Stop.Actions2,
+		ONgGameState->Input.Stopped.Actions2, ONgGameState->Input.Stopped.Actions2
+		);
+	*/	
+	ActiveCharacter * Active_Player = ONgGameState->ActiveCharacters;
+	
+	//if sprint timer is equal to 0, display 0
+	//else if sprint timer is equal to -1, display -1
+	//else display difference
+	//good thing this is just quick an dirty debug stuff :)
+
+	//basically it seems that if the difference is bigger than 15 frames, you cant dash. : /
+	
 #ifndef SPAM_INPUT
 	if(client_connected) 
@@ -457,5 +533,5 @@
 		flatline_packet input_packet = {0};
 		input_packet.id = PLAYER_INPUT;
-		
+		input_packet.input_struct.Time = ONgGameState->GameTime;
 		input_packet.input_struct.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
 		input_packet.input_struct.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
@@ -469,5 +545,5 @@
 #endif
 	//Testing drawing text to the screen...this failed. Will need to get it working eventually.
-	if( TSrTest ) 
+	if( TSrTest )
 	{
 	OniRectangle TextRect = { 20, 20, 50, 50 };
@@ -481,5 +557,6 @@
 		if(PlayerList[i] == 0) continue;
 		
-		Active_Player = (void*)ONrGetActiveCharacter(PlayerList[i]->Chr);
+		//is this right?
+		Active_Player = (void*)ONrGetActiveCharacter( PlayerList[i]->Chr);
 	
 		if(Active_Player == 0) continue;
@@ -499,4 +576,15 @@
 			data->DesiredFacing = PlayerList[i]->Chr->DesiredFacing;
 			data->CosmeticFacing = PlayerList[i]->Chr->CosmeticFacing;
+			data->Position = Active_Player->PhyContext->Position;
+			
+			if( PlayerList[i]->OldClass != PlayerList[i]->Chr->ONCC || memcmp( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) ) )
+			{
+				PlayerList[i]->OldClass = PlayerList[i]->Chr->ONCC;
+				memcpy( &(PlayerList[i]->Inventory), &(PlayerList[i]->Chr->Inventory), sizeof(Inventory) );
+				PlayerList[i]->rare_sync_index++;
+
+			}
+			
+			data->rare_sync_index = PlayerList[i]->rare_sync_index;
 			
 #if 0
@@ -531,12 +619,35 @@
 				data->Inputs.Actions2 = PlayerList[i]->Actions2;
 			}
+			memcpy( &(PlayerList[i]->player_data), data, sizeof(player_data) );
+			
 			UDPServer_SendToAll(&data_out, sizeof(player_data) + FLATLINE_HEADER);
 		}
 		
-		if( (server_started && i !=0) || (!server_started && i != client_slot)) {
+		if( (server_started && i !=0)  || (!server_started/* && i != client_slot*/) ) 
+		{
+			//this just made sync even worse....maybe keystrokes are actually _behind_
+			//
+			//
+#ifdef JITTER_FIX
+			input_struct * New_Input = &PlayerList[i]->MouseDeltaX;
+			input_struct * Cache_Input = &PlayerList[i]->CacheInput;
+			Active_Input->Stop.Actions1 = ~Cache_Input->Actions1 & Active_Input->Current.Actions1;
+			Active_Input->Stop.Actions2 = ~Cache_Input->Actions2 & Active_Input->Current.Actions2;
+			Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & Cache_Input->Actions1;
+			Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & Cache_Input->Actions2;
+			Active_Input->Current.Actions1 = Cache_Input->Actions1;
+			Active_Input->Current.Actions2 = Cache_Input->Actions2;
+			Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
+			Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
+			Active_Input->MouseDeltaX = Cache_Input->MouseDeltaX;
+			Active_Input->MouseDeltaY = Cache_Input->MouseDeltaY;
+			memcpy( Cache_Input, New_Input, sizeof(input_struct));
+#else
+	
 			Active_Input->Stop.Actions1 = ~PlayerList[i]->Actions1 & Active_Input->Current.Actions1;
 			Active_Input->Stop.Actions2 = ~PlayerList[i]->Actions2 & Active_Input->Current.Actions2;
 			Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Actions1;
 			Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Actions2;
+			
 			Active_Input->Current.Actions1 = PlayerList[i]->Actions1;
 			Active_Input->Current.Actions2 = PlayerList[i]->Actions2;
@@ -545,6 +656,54 @@
 			Active_Input->MouseDeltaX = PlayerList[i]->MouseDeltaX;
 			Active_Input->MouseDeltaY = PlayerList[i]->MouseDeltaY;
+			DDrConsole_PrintF("Timer: %i", (Active_Player->SprintTimer != 0) ? (Active_Player->SprintTimer == -1) ? -1 : (ONgGameState->GameTime - Active_Player->SprintTimer) : 0);
+
+			//DDrConsole_PrintF("1E8 %u", ONgGameState->PlayerCharacter->field_1E8);
+/*
+			DDrConsole_PrintF("T %u | Current: %x %x | Start: %x %x | Stop: %x %x | Stopped %x %x", 
+				PlayerList[i]->LastInputTime,
+				Active_Input->Current.Actions1, Active_Input->Current.Actions2,
+				Active_Input->Start.Actions1,Active_Input->Start.Actions2,
+				Active_Input->Stop.Actions1, Active_Input->Stop.Actions2,
+				Active_Input->Stopped.Actions1, Active_Input->Stopped.Actions2
+		);
+		*/
+			
+		
+#endif
+
+#ifdef BETTER_SYNC
+			if( !server_started && PlayerList[i]->player_data.Health != 0) {
+				PlayerList[i]->Chr->Health = PlayerList[i]->player_data.Health;
+				PlayerList[i]->Chr->MaxHealth = PlayerList[i]->player_data.MaxHealth;
+				PlayerList[i]->Chr->Position = PlayerList[i]->player_data.Position;
+				PlayerList[i]->Chr->Location = PlayerList[i]->player_data.Location;
+				PlayerList[i]->Chr->LastPosition = PlayerList[i]->player_data.LastPosition;
+				PlayerList[i]->Chr->Facing = PlayerList[i]->player_data.Facing;
+				PlayerList[i]->Chr->DesiredFacing = PlayerList[i]->player_data.DesiredFacing;
+				PlayerList[i]->Chr->CosmeticFacing = PlayerList[i]->player_data.CosmeticFacing;
+				PlayerList[i]->Actions1 = PlayerList[i]->player_data.Inputs.Actions1;
+				PlayerList[i]->Actions2 = PlayerList[i]->player_data.Inputs.Actions2;
+				PlayerList[i]->MouseDeltaX = PlayerList[i]->player_data.Inputs.MouseDeltaX;
+				PlayerList[i]->MouseDeltaY = PlayerList[i]->player_data.Inputs.MouseDeltaY;
+				Active_Player->PhyContext->Position = PlayerList[i]->player_data.Position;
+			}
+#endif
+
 		}
 	}
+
+	//Make the current controls match the sent controls, now that we have sent them off and everything is synced.
+	//No, don't do it to the direct input, it breaks stuff.
+	//Need to disable the function that puts game input onto characters because we are doing it directly.
+	/*
+	if( !server_started )
+	{
+		ONgGameState->Input.MouseDeltaX = PlayerList[client_slot]->MouseDeltaX;
+		ONgGameState->Input.MouseDeltaY = PlayerList[client_slot]->MouseDeltaY;
+		ONgGameState->Input.Current.Actions1 = PlayerList[client_slot]->Actions1;
+		ONgGameState->Input.Current.Actions2 = PlayerList[client_slot]->Actions2;
+	}
+	*/
+	
 	return ONgGameState;
 }
Index: Daodan/MSVC/Flatline.h
===================================================================
--- Daodan/MSVC/Flatline.h	(revision 567)
+++ Daodan/MSVC/Flatline.h	(revision 568)
@@ -65,10 +65,4 @@
 DWORD WINAPI StartClient(void* lol);
 
-//oh snap, I just realized this is rossy's version of flatline_packet. :|
-typedef struct {
-	char signature[8];
-	uint16_t protocol_version;
-	char data[0];				//data[0] doesn't work well with simple casts, btw. If you allocate enough space for a handshake_packet
-} handshake_packet;				//there won't be enough room for data. You would have to manually manage the memory (ew)
 
 //initial connection
@@ -98,5 +92,5 @@
 } new_player;
 
-extern int update_rate;
+//extern int update_rate;
 
 typedef struct {
@@ -105,4 +99,5 @@
 	uint32_t Actions1;
 	uint32_t Actions2;
+	unsigned int Time;
 } input_struct;
 
@@ -123,4 +118,6 @@
 	uint32_t MaxHealth;
 	input_struct Inputs;
+	int rare_sync_index;
+	//__int16 Varient;
 #if 0
 	uint16_t Frame;
@@ -144,4 +141,12 @@
 } player_data;
 
+//todo, move health in...
+typedef struct {
+	short unsigned int PlayerNum;
+	unsigned int index;
+	Inventory Inventory;
+	char Class[32];
+} rare_sync_data;
+
 //used for storing data about each player
 typedef struct {
@@ -158,7 +163,9 @@
 		server_status	server_status;
 		player_data		player_data;
+		rare_sync_data  rare_sync_data;
+		uint16_t		sync_request;
 	};
 } flatline_packet;
-#define FLATLINE_HEADER sizeof(flatline_packet)-sizeof(char)*1080
+#define FLATLINE_HEADER (sizeof(flatline_packet)-sizeof(char)*1080)
 //#define FLATLINE_PACKET_SIZE sizeof(flatline_packet) 
 
@@ -179,4 +186,6 @@
 	PLAYER_INPUT,
 	PLAYER_DATA,
+	RARE_SYNC_DATA,
+	RARE_SYNC_DATA_REQUEST,
 };
 
@@ -184,13 +193,22 @@
 typedef struct {
 	int	 ip;
-	char name[32];
+	char name[32]; 
 	char country[2];
 	Character* Chr;
 	uint16_t spawnnumber;
 	uint16_t list_slot;
+
+	float MouseDeltaX;
+	float MouseDeltaY;
 	uint32_t Actions1;
 	uint32_t Actions2;
-	float MouseDeltaX;
-	float MouseDeltaY;
+	unsigned int LastInputTime;
+	input_struct CacheInput;
+
+	player_data player_data;
+
+	unsigned int rare_sync_index;
+	void* OldClass;
+	Inventory Inventory;
 } player_info;
 
Index: Daodan/MSVC/Flatline_BSL.c
===================================================================
--- Daodan/MSVC/Flatline_BSL.c	(revision 567)
+++ Daodan/MSVC/Flatline_BSL.c	(revision 568)
@@ -114,16 +114,22 @@
 	return 0;
 }
-
-
+uint16_t ONICALL addfake(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret)
+{
+	player_info * info;
+info = FLrServer_AddPlayer( 0, "Fake", 0 );
+info->Actions1 = Action_Forward;
+return 0;
+}
 void SLrFlatline_Initialize() {
 	
-	DDrPatch_MakeCall(OniExe + 0x000FA88B, FLrInput_Update_Keys);
+	DDrPatch_MakeCall(0x004FA88B, FLrInput_Update_Keys);
+	
 	SLrGlobalVariable_Register_Int32("skip", "skips", &(((GameState*)ONgGameState)->field_40) );
 	SLrScript_Command_Register_ReturnType("connect","Connects to a server", "ip:string", sl_void, connect_to_server);
 	SLrScript_Command_Register_Void("host","Starts a server", "", start_server);
 	SLrScript_Command_Register_Void("msg","Sends a message", "", send_message);
-	SLrScript_Command_Register_Void("name","changes your name", "name:str", change_name);
+	SLrScript_Command_Register_ReturnType("name","changes your name", "name:str", sl_void, change_name);
 	SLrScript_Command_Register_Void("status","shows the connection status", "", status);
 	SLrGlobalVariable_Register_String("country", "Your Multiplayer country", player_name);
-	
+	SLrScript_Command_Register_ReturnType("addfakeclient","adds a fake client", "", sl_void, addfake);
 }
Index: Daodan/MSVC/Flatline_Server.c
===================================================================
--- Daodan/MSVC/Flatline_Server.c	(revision 567)
+++ Daodan/MSVC/Flatline_Server.c	(revision 568)
@@ -53,7 +53,12 @@
 		if(!is_server) { 
 			ONrGameState_NewCharacter(Char, NULL, NULL, &(player_slot));
+			//move this to a set up characters function...
+			ONgGameState->CharacterStorage[player_slot].field_1E8 = 0;
+
 			PlayerList[playerlist_slot] = Players+player_slot;
+			PlayerList[playerlist_slot]->spawnnumber = player_slot;
 			PlayerList[playerlist_slot]->Chr = &((Character *)(((GameState * )(ONgGameState))->CharacterStorage))[player_slot];
-			PlayerList[playerlist_slot]->Chr->Flags = chr_dontaim | chr_unkillable; //&= 0xFFBFFFFF; //WTF
+//			PlayerList[playerlist_slot]->Chr->Flags = chr_dontaim | chr_unkillable; //&= 0xFFBFFFFF; //WTF
+			PlayerList[playerlist_slot]->Chr->Flags &= 0xFFBFFFFF; //WTF
 			sprintf(PlayerList[playerlist_slot]->Chr->Name, "%.31s", name);		
 			UDPServer_SendToAll( (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
@@ -78,5 +83,26 @@
 void FLrServer_Initialize(){
 	FLrServer_AddPlayer(inet_addr("127.0.0.1"), "host", 1);
+}
 
-
+//UDPServer_SendToAll
+//Sends a packet to all the clients currently connected.
+//Returns the number of players sent to.
+int UDPServer_SendToAll(void* packet, int size) {
+	int j;
+	int players = 0;
+	sockaddr_in address;
+	memset(&address, 0, sizeof(sockaddr_in)); 
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = htonl(INADDR_ANY);
+	address.sin_port = htons(27777);
+	for(j = 0; j < max_connections; j++) {
+		if (PlayerList[j] != 0 && PlayerList[j]->ip && (PlayerList[j]->ip != inet_addr("127.0.0.1"))) {
+			int sent_bytes;
+			address.sin_addr.s_addr = htonl(PlayerList[j]->ip);//*((struct in_addr*)(int*)&(Players[j].ip));		
+			sent_bytes = NetUDPServer_Send((sockaddr *) &address, (char*)packet, size);
+			if(sent_bytes == SOCKET_ERROR) NetCatchError();
+			else players++;
+		}
+	}
+	return players;
 }
Index: Daodan/MSVC/Oni_GameState.h
===================================================================
--- Daodan/MSVC/Oni_GameState.h	(revision 567)
+++ Daodan/MSVC/Oni_GameState.h	(revision 568)
@@ -479,6 +479,40 @@
 } AttachedParticle;
 
+
+typedef struct 
+{
+  __int16 Index;
+  __int16 Flags;
+  int Class;
+  int Character;
+  Matrix4x3 Matrix;
+  int PhyContext;
+  int Facing;
+  __int16 FadeTimer;
+  __int16 TimeToFade;
+  int CreationTime;
+  __int16 ShotDelay1;
+  __int16 ShotDelay2;
+  __int16 PauseBeforeReload;
+  __int16 PauseAfterReload;
+  __int16 ActiveFireModeLength;
+  __int16 AmmoCount;
+  __int16 field_58;
+  __int16 FiringDelays[16];
+  char gap_7a[2];
+  int ParticleInstances[16];
+  int field_BC[16];
+  int field_FC;
+  int DodgeFiringSpreadPtr;
+  int field_104;
+  int field_108;
+  int field_10C;
+  char gap_110[20];
+  Vector3 Center;
+  int NodeList[16];
+} Weapon;
+
 typedef struct { //Inventory
-	int32_t Weapons[3];
+	Weapon* Weapons[3];
 	int16_t field_1A0; //10 bucks says this is the current weapon
 	int16_t AmmoUsed;				//Ammo given for the char to use
Index: Daodan/MSVC/Oni_Symbols.c
===================================================================
--- Daodan/MSVC/Oni_Symbols.c	(revision 567)
+++ Daodan/MSVC/Oni_Symbols.c	(revision 568)
@@ -141,4 +141,6 @@
 DefFunc( ONrPlatform_Initialize					, 0x0050f670 );
 DefFunc( ONrPlatform_WindowProc					, 0x0050f7a0 );
+DefFunc( iSetCharacterClass						, 0x004D99D0 );
+
 
 DefFunc( SLrGlobalVariable_Register_Int32		,	0x0477e30);
Index: Daodan/MSVC/Oni_Symbols.h
===================================================================
--- Daodan/MSVC/Oni_Symbols.h	(revision 567)
+++ Daodan/MSVC/Oni_Symbols.h	(revision 568)
@@ -113,4 +113,6 @@
 typedef int16_t ( *_TSrContext_New)( void* FontInstance, int size, int hthsik1,int hthsik2,int hthsik3, void* TSrContext); 
 
+//yes im cheating so badly.
+typedef uint16_t ( *_iSetCharacterClass)(sl_callinfo* callinfo, uint32_t numargs, sl_arg args[], int* dontuse1, int* dontuse2, sl_arg* ret);
 
 #define ExtFunc(name) extern _##name name
@@ -151,4 +153,6 @@
 ExtFunc(ONrGetActiveCharacter);
 
+ExtFunc(iSetCharacterClass);
+
 ExtFunc(COrTextArea_Print);
 
