Example #1
0
void GameEventsEnqueue(CArray *store, GameEvent e)
{
	if (store->elemSize == 0)
	{
		return;
	}
	// If we're the server, broadcast any events that clients need
	// If we're the client, pass along to server, but only if it's for a local player
	// Otherwise we'd ping-pong the same updates from the server
	const GameEventEntry gee = sGameEventEntries[e.Type];
	if (gee.Broadcast)
	{
		NetServerSendMsg(&gNetServer, NET_SERVER_BCAST, gee.Type, &e.u);
	}
	if (gee.Submit)
	{
		int actorUID = -1;
		bool actorIsLocal = false;
		switch (e.Type)
		{
		case GAME_EVENT_ACTOR_MOVE: actorUID = e.u.ActorMove.UID; break;
		case GAME_EVENT_ACTOR_STATE: actorUID = e.u.ActorState.UID; break;
		case GAME_EVENT_ACTOR_DIR: actorUID = e.u.ActorDir.UID; break;
		case GAME_EVENT_ACTOR_SLIDE: actorUID = e.u.ActorSlide.UID; break;
		case GAME_EVENT_ACTOR_SWITCH_GUN: actorUID = e.u.ActorSwitchGun.UID; break;
		case GAME_EVENT_ACTOR_PICKUP_ALL: actorUID = e.u.ActorPickupAll.UID; break;
		case GAME_EVENT_ACTOR_USE_AMMO: actorUID = e.u.UseAmmo.UID; break;
		case GAME_EVENT_ACTOR_MELEE: actorUID = e.u.Melee.UID; break;
		case GAME_EVENT_GUN_FIRE:
			if (e.u.GunFire.IsGun)
			{
				actorIsLocal = PlayerIsLocal(e.u.GunFire.PlayerUID);
			}
			break;
		case GAME_EVENT_GUN_RELOAD:
			actorIsLocal = PlayerIsLocal(e.u.GunReload.PlayerUID);
			break;
		case GAME_EVENT_GUN_STATE: actorUID = e.u.GunState.ActorUID; break;
		default: break;
		}
		if (actorUID >= 0)
		{
			actorIsLocal = ActorIsLocalPlayer(actorUID);
		}
		if (actorIsLocal)
		{
			NetClientSendMsg(&gNetClient, gee.Type, &e.u);
		}
	}

	CArrayPushBack(store, &e);
}
Example #2
0
static void OnReceive(NetClient *n, ENetEvent event)
{
	const NetMsg msgType = (NetMsg)*(uint32_t *)event.packet->data;
	LOG(LM_NET, LL_TRACE, "recv msg(%u)", msgType);
	const NetMsgEntry nme = NetMsgGet(msgType);
	if (nme.Event != GAME_EVENT_NONE)
	{
		// Game event message; decode and add to event queue
		LOG(LM_NET, LL_DEBUG, "recv gameEvent(%d)", (int)nme.Event);
		GameEvent e = GameEventNew(nme.Event);
		if (nme.Fields != NULL)
		{
			NetDecode(event.packet, &e.u, nme.Fields);
		}

		// For actor events, check if UID is not for local player
		int actorUID = -1;
		bool actorIsLocal = false;
		switch (nme.Event)
		{
		case GAME_EVENT_ACTOR_ADD:
			// Note: ignore checking this event
			break;
		case GAME_EVENT_ACTOR_MOVE: actorUID = e.u.ActorMove.UID; break;
		case GAME_EVENT_ACTOR_STATE: actorUID = e.u.ActorState.UID; break;
		case GAME_EVENT_ACTOR_DIR: actorUID = e.u.ActorDir.UID; break;
		case GAME_EVENT_ADD_BULLET:
			actorIsLocal = PlayerIsLocal(e.u.AddBullet.PlayerIndex);
			break;
		default: break;
		}
		if (actorUID >= 0)
		{
			actorIsLocal = ActorIsLocalPlayer(actorUID);
		}
		if (actorIsLocal)
		{
			LOG(LM_NET, LL_TRACE, "game event is for local player, ignoring");
		}
		else
		{
			GameEventsEnqueue(&gGameEvents, e);
		}
	}
	else
	{
		switch (msgType)
		{
		case MSG_CLIENT_ID:
			{
				CASSERT(
					n->ClientId == -1,
					"unexpected client ID message, already set");
				NetMsgClientId cid;
				NetDecode(event.packet, &cid, NetMsgClientId_fields);
				LOG(LM_NET, LL_DEBUG, "NetClient: received client ID %d", cid.Id);
				n->ClientId = cid.Id;
			}
			break;
		case MSG_CAMPAIGN_DEF:
			if (gCampaign.IsLoaded)
			{
				LOG(LM_NET, LL_INFO, "WARNING: unexpected campaign def msg received");
			}
			else
			{
				LOG(LM_NET, LL_DEBUG, "NetClient: received campaign def, loading...");
				NetMsgCampaignDef def;
				NetDecode(event.packet, &def, NetMsgCampaignDef_fields);
				char campaignPath[CDOGS_PATH_MAX];
				GameMode mode;
				NetMsgCampaignDefConvert(&def, campaignPath, &mode);
				CampaignEntry entry;
				if (CampaignEntryTryLoad(&entry, campaignPath, mode) &&
					CampaignLoad(&gCampaign, &entry))
				{
					gCampaign.IsClient = true;
				}
				else
				{
					printf("Error: failed to load campaign def\n");
					gCampaign.IsError = true;
				}
			}
			break;
		case MSG_PLAYER_DATA:
			{
				NetMsgPlayerData pd;
				NetDecode(event.packet, &pd, NetMsgPlayerData_fields);
				AddMissingPlayers(pd.PlayerIndex);
				LOG(LM_NET, LL_DEBUG, "recv player data name(%s) id(%d) total(%d)",
					pd.Name, pd.PlayerIndex, (int)gPlayerDatas.size);
				NetMsgPlayerDataUpdate(&pd);
			}
			break;
		case MSG_ADD_PLAYERS:
			{
				NetMsgAddPlayers ap;
				NetDecode(event.packet, &ap, NetMsgAddPlayers_fields);
				LOG(LM_NET, LL_DEBUG,
					"NetClient: received new players %d",
					(int)ap.PlayerIds_count);
				// Add new players
				// If they are local players, set them up with defaults
				const bool isLocal = ap.ClientId == n->ClientId;
				for (int i = 0; i < ap.PlayerIds_count; i++)
				{
					const int playerId = (int)ap.PlayerIds[i];
					AddMissingPlayers(playerId);
					PlayerData *p = CArrayGet(&gPlayerDatas, playerId);
					p->IsLocal = isLocal;
					if (isLocal)
					{
						PlayerDataSetLocalDefaults(p, i);
					}
				}
			}
			break;
		case MSG_GAME_START:
			LOG(LM_NET, LL_DEBUG, "NetClient: received game start");
			gMission.HasStarted = true;
			break;
		case MSG_GAME_END:
			LOG(LM_NET, LL_DEBUG, "NetClient: received game end");
			gMission.isDone = true;
			break;
		default:
			CASSERT(false, "unexpected message type");
			break;
		}
	}
	enet_packet_destroy(event.packet);
}