//============================================================================== // Contains information about the existing voice chat channels on the server. // This class is simply a placeholder for the VoiceReplicationInfo, and should // be implemented in a multi-player capable subclass. // // Created by Ron Prestenback // © 2003, Epic Games, Inc. All Rights Reserved //============================================================================== class VoiceChatReplicationInfo extends ReplicationInfo config abstract notplaceable native nativereplication; cpptext { INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel ); } const NUMPROPS = 6; struct native VoiceChatCodec { var string Codec; var localized string CodecName; var localized string CodecDescription; }; var int PublicMask, LocalMask; // Array of chatroom channels var protected array Channels; var localized array PublicChannelNames; var localized string VCDisplayText[NUMPROPS], VCDescText[NUMPROPS]; var GameReplicationInfo GRI; var class ChatRoomClass; var array InstalledCodec; var globalconfig array VoIPInternetCodecs; var globalconfig array VoIPLANCodecs; var globalconfig bool bEnableVoiceChat; // Whether voice over IP is enabled on this server var globalconfig bool bAllowLocalBroadcast; // Whether this server allows local channels var globalconfig int MaxChatters; // Max number of chatters allowed in a chatroom (0 - unlimited) var int DefaultChannel; // Channel that should be the default active channel for incoming clients that don't specify a default active channel var globalconfig float LocalBroadcastRange; // Maximum distance a local broadcast can be heard var globalconfig float DefaultBroadcastRadius; // Distance at which broadcast volume begins to fade var float BroadcastRadius; var bool bPrivateChat; // Set by UnrealMPGameInfo.InitVoiceReplicationInfo() var bool bRefresh; // Indicates a chat room has destroyed itself replication { reliable if ( Role == ROLE_Authority && bNetInitial ) bEnableVoiceChat; reliable if ( Role == ROLE_Authority && bNetInitial && bEnableVoiceChat ) bPrivateChat; reliable if ( Role == ROLE_Authority && bNetInitial && bEnableVoiceChat && bAllowLocalBroadcast ) BroadcastRadius; reliable if ( Role == ROLE_Authority && bNetDirty && bEnableVoiceChat ) PublicMask, LocalMask; reliable if ( Role == ROLE_Authority && (bNetInitial || bNetDirty) && bEnableVoiceChat ) DefaultChannel; } event Timer() { // One of our channels has destroyed itself if (bRefresh) CheckChannels(); } event PostBeginPlay() { Super.PostBeginPlay(); if ( bAllowLocalBroadcast ) BroadcastRadius = FMin(LocalBroadcastRange, FClamp(DefaultBroadcastRadius, 10, 1000)); } simulated event PostNetBeginPlay() { // Initialize all public channels. if ( bEnableVoiceChat ) { InitChannels(); SetTimer(1.0, True); } } simulated function InitChannels(); // This is called when a new player has logged into the server. simulated function AddVoiceChatter(PlayerReplicationInfo NewPRI); // Called when a player logs out simulated function RemoveVoiceChatter(PlayerReplicationInfo PRI); // Used to prescreen whether 'PRI' would be allowed to join channel with title 'ChannelTitle' simulated function bool CanJoinChannel(string ChannelTitle, PlayerReplicationInfo PRI) { return true; } // Joins / Leaves // Called when player requests to join channel function VoiceChatRoom.EJoinChatResult JoinChannel(string ChannelTitle, PlayerReplicationInfo PRI, string Password) { return JCR_Invalid; } function VoiceChatRoom.EJoinChatResult JoinChannelAt(int ChannelIndex, PlayerReplicationInfo PRI, string Password) { return JCR_Invalid; } // Called when player leaves channel function bool LeaveChannel(string ChannelTitle, PlayerReplicationInfo PRI) { return true; } // Channel management simulated function VoiceChatRoom AddVoiceChannel(optional PlayerReplicationInfo PRI) { return None; } simulated function bool RemoveVoiceChannel(PlayerReplicationInfo PRI) { return true; } // Called on all voice channels when a player switches teams. Disregarded by voice channel if TeamIndex doesn't match channel's teamindex simulated function NotifyTeamChange(PlayerReplicationInfo PRI, int TeamIndex); // Query Functions simulated event int GetChannelCount() { return 0; } simulated event int GetChannelIndex(string ChannelTitle, optional int TeamIndex) { return -1; } simulated function VoiceChatRoom GetChannel(string ChatRoomName, optional int TeamIndex) { return None; } simulated function VoiceChatRoom GetChannelAt(int Index) { return None; } // Returns a list of members in the specified channel simulated function array GetChannelMembers(string ChatRoomName, optional int TeamIndex); simulated function array GetChannelMembersAt(int Index); // Returns a list of channels that the specified player is a member of simulated function array GetMemberChannels( PlayerReplicationInfo PRI ); simulated function string GetDefaultChannel() { return PublicChannelNames[Clamp(DefaultChannel,0,PublicChannelNames.Length - 1)]; } simulated function array GetChannels(); simulated function array GetPublicChannels(); simulated function array GetPlayerChannels(); simulated function int GetPublicChannelCount(optional bool bSingleTeam); simulated function int GetPlayerChannelCount(); // Returns whether 'TestPRI' is a member of this channel. If bNoCacade is false, will return true if player is member of child channels simulated function bool IsMember(PlayerReplicationInfo TestPRI, int ChannelIndex, optional bool bNoCascade) { return false; } // Internal functions simulated protected function VoiceChatRoom CreateNewVoiceChannel(optional PlayerReplicationInfo PRI) { return None; } // Called from RemoveVoiceChatter() simulated protected function DestroyVoiceChannel(VoiceChatRoom Channel); simulated private function CheckChannels() { local int i; for (i = Channels.Length - 1; i >= 0; i--) if (Channels[i] == None) Channels.Remove(i,1); bRefresh = False; } static function FillPlayInfo( PlayInfo PlayInfo ) { Super.FillPlayInfo( PlayInfo ); PlayInfo.AddSetting( default.ChatGroup, "bEnableVoiceChat", default.VCDisplayText[0], 250, 1, "Check", , "Xv", True, True); PlayInfo.AddSetting( default.ChatGroup, "bAllowLocalBroadcast", default.VCDisplayText[1], 250, 1, "Check", , "Xv", True, True); PlayInfo.AddSetting( default.ChatGroup, "LocalBroadcastRange", default.VCDisplayText[2], 100, 1, "Text", "4;10:3000", "Xv", True, True); PlayInfo.AddSetting( default.ChatGroup, "DefaultBroadcastRadius", default.VCDisplayText[3], 100, 1, "Text", "4;10:1000", "Xv", True, True); PlayInfo.AddSetting( default.ChatGroup, "VoIPInternetCodecs", default.VCDisplayText[4], 254, 1, "Text", , "Xv", True, True); PlayInfo.AddSetting( default.ChatGroup, "VoIPLANCodecs", default.VCDisplayText[5], 254, 1, "Text", , "Xv", True, True); } static event string GetDescriptionText( string PropName ) { switch ( PropName ) { case "bEnableVoiceChat": return default.VCDescText[0]; case "bAllowLocalBroadcast": return default.VCDescText[1]; case "LocalBroadcastRange": return default.VCDescText[2]; case "DefaultBroadcastRadius": return default.VCDescText[3]; case "VoIPInternetCodecs": return default.VCDescText[4]; case "VoIPLANCodecs": return default.VCDescText[5]; } return Super.GetDescriptionText(PropName); } static function GetInstalledCodecs( out array Codecs ) { local int i; Codecs.Length = default.InstalledCodec.Length; for ( i = 0; i < default.InstalledCodec.Length; i++ ) Codecs[i] = default.InstalledCodec[i].Codec; } static function bool GetCodecInfo( string Codec, out string CodecName, out string CodecDescription ) { local int i; for ( i = 0; i < default.InstalledCodec.Length; i++ ) { if ( Codec ~= default.InstalledCodec[i].Codec ) { CodecName = default.InstalledCodec[i].CodecName; CodecDescription = default.InstalledCodec[i].CodecDescription; return true; } } return false; } simulated function bool ValidRoom( VoiceChatRoom Room ) { return bEnableVoiceChat && Room != None && Room.ChannelIndex < 2 && Room.Owner == Self; } function SetMask( VoiceChatRoom Room, int NewMask ) { if ( !ValidRoom(Room) ) return; if ( Room.ChannelIndex == 0 ) PublicMask = NewMask; else if ( Room.ChannelIndex == 1 ) LocalMask = NewMask; } simulated function int GetMask( VoiceChatRoom Room ) { if ( !ValidRoom(Room) ) return 0; if ( Room.ChannelIndex == 0 ) return PublicMask; if ( Room.ChannelIndex == 1 ) return LocalMask; return 0; } simulated function string GetTitle( VoiceChatRoom Room ) { if ( !ValidRoom(Room) ) return ""; return PublicChannelNames[Room.ChannelIndex]; } DefaultProperties { NetPriority=3.001 ChatRoomClass=class'Engine.VoiceChatRoom' PublicChannelNames(0)="Public" PublicChannelNames(1)="Local" InstalledCodec[0]=(Codec="CODEC_48NB",CodecName="Less Bandwidth",CodecDescription="(4.8kbps) - Uses less bandwidth, but sound is not as clear.") InstalledCodec[1]=(Codec="CODEC_96WB",CodecName="Better Quality",CodecDescription="(9.6kbps) - Uses more bandwidth, but sound is much clearer.") VCDisplayText[0]="Enable Voice Chat" VCDisplayText[1]="Enable local Channel" VCDisplayText[2]="Local Chat Range" VCDisplayText[3]="Local Chat Radius" VCDisplayText[4]="Allowed VoIP Codecs" VCDisplayText[5]="Allowed VoIP LAN Codecs" VCDescText[0]="Enable voice chat on the server." VCDescText[1]="Determines whether the \"local\" voice chat channel is created, which allows players to broadcast voice transmissions to all players in the immediate vicinity." VCDescText[2]="Maximum distance at which a broadcast on the local channel may be heard" VCDescText[3]="Distance at which local broadcasts begin to fade" VCDescText[4]="Configure which codecs exist on the server and should be used in Internet games." VCDescText[5]="Configure which codecs exist on the server and should be used in LAN games." bEnableVoiceChat=True bAllowLocalBroadcast=True LocalBroadcastRange=1000 DefaultBroadcastRadius=20 VoIPInternetCodecs[0]="CODEC_48NB" VoIPLANCodecs[0]="CODEC_48NB" VoIPLANCodecs[1]="CODEC_96WB" }