18/10/2022 21:10
(13/06/2022 05:03)OTAKEIRO Escreveu: Num testei... Afinal voip é meio complicado de mexer, mas acho que deve funcionar, tudo o que voce precisa fazer pra complementar é ativar o microfone quando o jogador pressionar para falar e usar DisconnectPlayer em OnPlayerDisconnect, em OnGameModeExit e em OnFilterScriptInit para prevenir que um canal não usado permaneça ocupando a memoria
Código:enum SERVER_RADIO
{
Channel,
Listener,
SV_PTR:Audio
}
new
P_Radio[MAX_PLAYERS],
S_Radio[MAX_PLAYERS][SERVER_RADIO];
new Iterator:I_Radio<MAX_PLAYERS>;
CMD:radio(playerid, params[])
{
new string[255], integer;
if(sscanf(params, "d", integer))
{
if(P_Radio[playerid])
{
format(string, sizeof(string), "[RADIO] Seu canal atual: %d", P_Radio[playerid]);
SendClientMessage(playerid, -1, string);
}
SendClientMessage(playerid, -1, "[RADIO] Utilize /radio [1 a 9999] para alterar o canal");
SendClientMessage(playerid, -1, "[RADIO] Utilize /radio 0 para desligar o radio");
}
else
{
if(P_Radio[playerid] != integer)
{
if(integer == 0)
{
integer = FindChannel(integer);
DisconnectPlayer(playerid, integer);
SendClientMessage(playerid, -1, "[RADIO] O seu radio foi desligado!");
}
else if(1 <= integer <= 9999)
{
DisconnectPlayer(playerid);
P_Radio[playerid] = integer;
if(!FindChannel(integer))
{
integer = Iter_Free(I_Radio);
Iter_Add(I_Radio, integer);
S_Radio[integer][Channel] = P_Radio[playerid];
S_Radio[integer][Audio] = SvCreateGStream(0, "Radio");
}
SvAttachListenerToStream(S_Radio[channel][Audio], playerid);
SvAttachSpeakerToStream(S_Radio[channel][Audio], playerid);
S_Radio[channel][Listener]++;
format(string, sizeof(string), "[RADIO] Voce foi conectado ao canal: %d", P_Radio[playerid]);
SendClientMessage(playerid, -1, string);
}
else CallLocalFunction("OnPlayerCommandText", "ds", playerid, "/radio");
}
else
{
if(integer == 0) SendClientMessage(playerid, -1, "[ERRO] O seu radio nao esta ligado!");
else SendClientMessage(playerid, -1, "[ERRO] Voce ja esta ouvindo esse canal!");
}
}
return 1;
}
FindChannel(&dest)
{
foreach(new i : I_Radio)
{
if(S_Radio[i][Channel] == dest)
{
dest = i;
return 1;
}
}
return 0;
}
DisconnectPlayer(playerid, channel = P_Radio[playerid])
{
SvDetachListenerFromStream(S_Radio[channel][Audio], playerid);
SvDetachSpeakerFromStream(S_Radio[channel][Audio], playerid);
P_Radio[playerid] = 0;
if(0 == --S_Radio[channel][Listener])
{
Iter_Remove(I_Radio, channel);
SvDeleteStream(S_Radio[channel][Audio]);
}
}
Fiz com que o canal fosse deletado se nao tivesse ouvintes
E usei iterador pra pesquisar um campo livre no array pq o array é de 1000 caracters (padrão do MAX_PLAYERS), acho desnecessário um array de 9999
Opa desculpa a demora, não vi sua resposta
Tentei adaptar sua sugestão pra FilterScript pra todo mundo aqui do fórum conseguir usar, já que muitos pedem esse sistema, mas quando um jogador da /radio 1 o servidor crasha
Código:
#include <a_samp>
#include <sampvoice>
#include <sscanf2>
#include <zcmd>
// global chat adm 1
new SV_GSTREAM:gstream = SV_NULL;
// local chat player 1
new SV_LSTREAM:lstream[MAX_PLAYERS] = { SV_NULL, ... };
// radio 1
enum SERVER_RADIO
{
Channel,
Listener,
SV_PTR:Audio,
}
new P_Radio[MAX_PLAYERS];
new S_Radio[MAX_PLAYERS][SERVER_RADIO];
forward DisconnectPlayerFromRadio(playerid, channel);
forward FindChannelFromRadio(dest);
new Last_Iter_Radio = 0;
// GM 1
// new GetPVarInt(playerid,"hasVoiceOnClient")
// 0 = sem voice, 1 = com voice, 2 = com voice, sem mic
// GM 2
// GetPVarInt(playerid,"talkStats")
// tipo de fala pra verificar se ta falando no chat ou no radio
// GM 3
// GetPVarInt(playerid,"admin")
// pra dizer se é admin
public SV_VOID:OnPlayerActivationKeyPress(SV_UINT:playerid, SV_UINT:keyid)
{
// Press 'B'
if (keyid == 0x42) {
// radio voice 2
new rfid = GetPVarInt(playerid,"radio_frequency");
if(GetPVarInt(playerid,"talkStats") == 3) {
if(S_Radio[rfid][Audio]) SvAttachSpeakerToStream(S_Radio[rfid][Audio], playerid);
}
// local chat player 2
else {
if(lstream[playerid]) SvAttachSpeakerToStream(lstream[playerid], playerid);
}
}
// Press 'Z' (admins)
if(GetPVarInt(playerid,"admin") >= 6) {
if (keyid == 0x5A && gstream) SvAttachSpeakerToStream(gstream, playerid);
}
}
public SV_VOID:OnPlayerActivationKeyRelease(SV_UINT:playerid, SV_UINT:keyid)
{
// Release 'B'
if (keyid == 0x42) {
if(lstream[playerid]) SvDetachSpeakerFromStream(lstream[playerid], playerid);
new rfid = GetPVarInt(playerid,"radio_frequency");
if (S_Radio[rfid][Audio]) SvDetachSpeakerFromStream(S_Radio[rfid][Audio], playerid);
}
// Release 'Z'
if (keyid == 0x5A) {
if(gstream) SvDetachSpeakerFromStream(gstream, playerid);
}
}
public OnPlayerConnect(playerid) {
// Checking for plugin availability
if (SvGetVersion(playerid) == SV_NULL)
{
SendClientMessage(playerid, -1, "Could not find plugin sampvoice.");
SetPVarInt(playerid,"hasVoiceOnClient",0);
}
// Checking for a microphone
else if (SvHasMicro(playerid) == SV_FALSE)
{
SendClientMessage(playerid, -1, "The microphone could not be found.");
SetPVarInt(playerid,"hasVoiceOnClient",2);
}
// Create a local stream with an audibility distance of 40.0, an unlimited number of listeners
// and the name 'Local' (the name 'Local' will be displayed in red in the players' speakerlist)
else if ((lstream[playerid] = SvCreateDLStreamAtPlayer(40.0, SV_INFINITY, playerid, 0xff0000ff, "Local")))
{
// Attach the player to the global stream as a listener
if (gstream) SvAttachListenerToStream(gstream, playerid);
// Assign microphone activation keys to the player
SvAddKey(playerid, 0x42);
SvAddKey(playerid, 0x5A);
//
SetPVarInt(playerid,"hasVoiceOnClient",1);
}
}
public OnPlayerDisconnect(playerid, reason) {
// Removing the player's local stream after disconnecting
if (lstream[playerid])
{
SvDeleteStream(lstream[playerid]);
lstream[playerid] = SV_NULL;
}
// remove radio stream after disconnecting
new rfid = GetPVarInt(playerid,"radio_frequency");
if(S_Radio[rfid][Audio]) {
SvDeleteStream(S_Radio[rfid][Audio]);
S_Radio[rfid][Audio] = SV_NULL;
}
}
public OnFilterScriptInit() {
// samp voice 5
gstream = SvCreateGStream(0xffff0000, "Global");
// radio, prevenir que um canal não usado permaneça ocupando a memoria
for(new i = 0; i < Last_Iter_Radio; i++)
{
if(S_Radio[i][Audio]) {
SvDeleteStream(S_Radio[i][Audio]);
}
}
}
public OnFilterScriptExit() {
// samp voice 6
if (gstream) SvDeleteStream(gstream);
// radio, prevenir que um canal não usado permaneça ocupando a memoria
for(new i = 0; i < Last_Iter_Radio; i++)
{
if(S_Radio[i][Audio]) {
SvDeleteStream(S_Radio[i][Audio]);
}
}
}
// radio voice 5
public DisconnectPlayerFromRadio(playerid, channel)
{
P_Radio[playerid] = 0;
if(channel != 0)
{
SvDetachListenerFromStream(S_Radio[channel][Audio], playerid);
SvDetachSpeakerFromStream(S_Radio[channel][Audio], playerid);
if(0 == --S_Radio[channel][Listener])
{
Last_Iter_Radio--;
SvDeleteStream(S_Radio[channel][Audio]);
}
}
}
public FindChannelFromRadio(dest)
{
for(new i = 0; i < Last_Iter_Radio; i++)
{
if(S_Radio[i][Channel] == dest)
{
dest = i;
return 1;
}
}
return 0;
}
CMD:radio(playerid, params[])
{
new string[255], integer;
if(sscanf(params, "d", integer))
{
if(P_Radio[playerid])
{
format(string, sizeof(string), "[RADIO] Seu canal atual: %d", P_Radio[playerid]);
SendClientMessage(playerid, -1, string);
}
SendClientMessage(playerid, -1, "[RADIO] Utilize /radio [1 a 9999] para alterar o canal");
SendClientMessage(playerid, -1, "[RADIO] Utilize /radio 0 para desligar o radio");
return true;
}
if(P_Radio[playerid] != integer)
{
// invalido
if(integer < 1 || integer > 9999) {
SendClientMessage(playerid, -1, "As frequencias so vao de 1 a 9999!");
return true;
}
// 0 = desligar radio
if(integer == 0)
{
DisconnectPlayerFromRadio(playerid, P_Radio[playerid]);
SendClientMessage(playerid, -1, "[RADIO] O seu radio foi desligado!");
}
// trocar de frequencia
else if(1 <= integer <= 9999)
{
if(P_Radio[playerid] != 0) DisconnectPlayerFromRadio(playerid, P_Radio[playerid]);
P_Radio[playerid] = integer;
if(!FindChannelFromRadio(integer))
{
Last_Iter_Radio++;
S_Radio[integer][Channel] = P_Radio[playerid];
S_Radio[integer][Audio] = SvCreateGStream(0, "Radio");
}
SvAttachListenerToStream(S_Radio[integer][Audio], playerid);
S_Radio[integer][Listener]++;
format(string, sizeof(string), "[RADIO] Voce foi conectado ao canal: %d", P_Radio[playerid]);
SendClientMessage(playerid, -1, string);
}
}
else
{
if(integer == 0) SendClientMessage(playerid, -1, "[ERRO] O seu radio nao esta ligado!");
else SendClientMessage(playerid, -1, "[ERRO] Voce ja esta ouvindo esse canal!");
}
return 1;
}
fiz algo errado ou tem algo errado no script mesmo?