Raised This Month: $51 Target: $400
 12% 

SetListenOverride Issues


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
zeroibis
Veteran Member
Join Date: Jun 2007
Old 01-31-2011 , 19:17   SetListenOverride Issues
Reply With Quote #1

Does anyone else have issues with SetListenOverride not working correctly when all talk is on?

Sometimes this works and sometimes it does not. It has random functionality:

Code:
for (new i = 1; i <= MaxClients; i++) 
        {
            if (i != client && IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) != myteam)
            {
                if(IsPlayerAlive(i))
                {
                    SetListenOverride(i, client, Listen_No);
                }
            }
        }
__________________
zeroibis is offline
kossolax
AlliedModders Donor
Join Date: Jan 2008
Location: Belgium
Old 02-01-2011 , 09:23   Re: SetListenOverride Issues
Reply With Quote #2

For me, I'm using a local-talk script.
It's crashing after some time, and the only way to have the SetListenOverride working again. It's to restart the server using exit command.
kossolax is offline
zeroibis
Veteran Member
Join Date: Jun 2007
Old 02-01-2011 , 22:31   Re: SetListenOverride Issues
Reply With Quote #3

Any idea what causes the script to fail? I can not find anything in the error logs.
__________________
zeroibis is offline
databomb
Veteran Member
Join Date: Jun 2009
Location: california
Old 02-01-2011 , 23:09   Re: SetListenOverride Issues
Reply With Quote #4

I was having the same problems with this function. It might have something to do with having too many over-rides being issued. There are certain plugins such as Admin Sentinel that have a very small number of over-rides and work without incident.

Have you tried starting with sv_alltalk 0 and coding the over-rides from that starting point? I had more luck with that until it randomly breaks and I have to exit to restore normal functionality. Re-loading the sdktools extension might help too so you don't have to completely exit out.
databomb is offline
zeroibis
Veteran Member
Join Date: Jun 2007
Old 02-01-2011 , 23:48   Re: SetListenOverride Issues
Reply With Quote #5

Still this indicates a problem then with the actual function and is something that we should try to get the developers to look into patching then. On a more possible quick fix is there a way for us to catch when it breaks and then automatically issue the sdkhooks reset!?
__________________
zeroibis is offline
databomb
Veteran Member
Join Date: Jun 2009
Location: california
Old 02-02-2011 , 01:08   Re: SetListenOverride Issues
Reply With Quote #6

We could re-build the 65x65 array with GetListenOverride or test an individual instance to make sure the SetListenOverride was effective. That's assuming the array will show the status of the voice hooks correctly when it's broken. Dynamically re-loading the sdktools.. well, doing it with plugins loaded has caused me seg faults in the past. Perhaps a cfg script that would unload all plugins, then unload sdktools, wait a second, reload sdktools, then reload all plugins.
databomb is offline
databomb
Veteran Member
Join Date: Jun 2009
Location: california
Old 02-02-2011 , 01:40   Re: SetListenOverride Issues
Reply With Quote #7

In SourceMod SDKTools extension:
PHP Code:
void SDKTools::VoiceInit()
{
    
memset(g_VoiceMap0sizeof(g_VoiceMap));
    
memset(g_ClientOverrides0sizeof(g_ClientOverrides));
    
memset(g_ClientMutes0sizeof(g_ClientMutes));

    
SH_ADD_HOOK_MEMFUNC(IServerGameClientsClientCommandserverClientsthis, &SDKTools::OnClientCommandtrue);

Then whenever IncHookCount
PHP Code:
void IncHookCount()
{
    if (!
g_VoiceHookCount++)
    {
        
SH_ADD_HOOK_MEMFUNC(IVoiceServerSetClientListeningvoiceserver, &g_SdkTools, &SDKTools::OnSetClientListeningfalse);
    }

In mani (where dead all talk is confirmed to work)
PHP Code:
void    ManiSMMHooks::HookVFuncs(void)
{
    if (
voiceserver && gpManiGameType->IsVoiceAllowed())
    {
        
//MMsg("Hooking voiceserver\n");
        
SH_ADD_HOOK_MEMFUNC(IVoiceServerSetClientListeningvoiceserver, &g_ManiSMMHooks, &ManiSMMHooks::SetClientListeningfalse); // changed to false by Keeper
    

Whenever we do an override or listening flags call that results in an override, IncHookCount is called in SM, which is the first place to initialize the VoiceServer hook if there weren't any previous hooks. In Mani it seems like it's done at initiation and that's it.

Also in SM there is:
PHP Code:
bool SDKTools::OnSetClientListening(int iReceiverint iSenderbool bListen)
{
    if (
g_ClientMutes[iReceiver][iSender])
    {
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSenderfalse));
    }

    if (
g_VoiceMap[iReceiver][iSender] == Listen_No)
    {
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSenderfalse));
    }
    else if (
g_VoiceMap[iReceiver][iSender] == Listen_Yes)
    {
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSendertrue));
    }

    if (
g_VoiceFlags[iSender] & SPEAK_MUTED)
    {
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSenderfalse));
    }

    if ((
g_VoiceFlags[iSender] & SPEAK_ALL) || (g_VoiceFlags[iReceiver] & SPEAK_LISTENALL))
    {
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSendertrue));
    }

    if ((
g_VoiceFlags[iSender] & SPEAK_TEAM) || (g_VoiceFlags[iReceiver] & SPEAK_LISTENTEAM))
    {
        
IGamePlayer *pReceiver playerhelpers->GetGamePlayer(iReceiver);
        
IGamePlayer *pSender playerhelpers->GetGamePlayer(iSender);

        if (
pReceiver && pSender && pReceiver->IsInGame() && pSender->IsInGame())
        {
            
IPlayerInfo *pRInfo pReceiver->GetPlayerInfo();
            
IPlayerInfo *pSInfo pSender->GetPlayerInfo();

            if (
pRInfo && pSInfo && pRInfo->GetTeamIndex() == pSInfo->GetTeamIndex())
            {
                
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSendertrue));
            }
        }
    }

    
RETURN_META_VALUE(MRES_IGNOREDbListen);

and in Mani we have:
PHP Code:
bool    ManiSMMHooks::SetClientListening(int iReceiverint iSenderbool bListen)
{
    
bool new_listen false;

    if ( 
iSender == iReceiver )
        
RETURN_META_VALUE MRES_IGNOREDbListen );

    if (
ProcessMuteTalk(iReceiveriSender, &new_listen))
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSendernew_listen));

    if (
ProcessDeadAllTalk(iReceiveriSender, &new_listen))
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSendernew_listen));

    
RETURN_META_VALUE(MRES_IGNOREDbListen );

In SM there's no check for if Sender == Receiver.. I started putting that check inside my SourcePawn FOR loops and maybe that was around the same time that the voice hooks started lasting a lot longer before eventually and randomly dying at some later point.

Last edited by databomb; 02-02-2011 at 17:35. Reason: added clientlistening comparisons
databomb is offline
databomb
Veteran Member
Join Date: Jun 2009
Location: california
Old 02-02-2011 , 17:42   Re: SetListenOverride Issues
Reply With Quote #8

Looking over the code some more... maybe it has more to do with disconnect situations. This would explain why we think it occurs randomly and there's probably a way to code around it if it's true.

PHP Code:
void SDKTools::OnClientDisconnecting(int client)
{
    
g_Hooks.OnClientDisconnecting(client);

    
int max_clients playerhelpers->GetMaxClients();

    if (
g_VoiceHookCount == 0)
    {
        return;
    }

    
/* This can probably be optimized more, but I doubt it's that much 
     * of an actual bottleneck.
     */

    /* Reset other clients who receive from or have muted this client */
    
for (int i 1<= max_clientsi++)
    {
        if (
== client)
        {
            continue;
        }

        
g_ClientMutes[i][client] = false;
        
        if (
g_VoiceMap[i][client] != Listen_Default)
        {
            
g_VoiceMap[i][client] = Listen_Default;
            if (
DecHookCount())
            {
                break;
            }
        }
    }

    
/* Reset this client's mutes */
    
memset(&g_ClientMutes[client], 0sizeof(bool) * 65);

    
/* Reset other clients who send to this client */
    
if (g_ClientOverrides[client] > 0)
    {
        
DecHookCount(g_ClientOverrides[client]);
        
g_ClientOverrides[client] = 0;
        
memset(&g_VoiceMap[client], falsesizeof(ListenOverride) * 65);
    }

    if (
g_VoiceFlags[client])
    {
        
g_VoiceFlags[client] = 0;
        
DecHookCount();
    }

The regular voice flags don't ever seem to scramble the system, so the g_VoiceFlags part at the end looks fine. There's a lot of useless stuff having to do with clientside muting that I don't think any plugin uses. So maybe it's a problem with how these loops are processed. If DecHookCount ever un-registered the voiceserver hook, it'd explain why re-loading the sdktools extension solves the problem.
databomb is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 02-02-2011 , 19:02   Re: SetListenOverride Issues
Reply With Quote #9

Hooks are counted because we don't want hooks existing when not used. This prevents crashes in the case where Valve changes the interface in some patch but you're not using that functionality.

You say "a lot of useless stuff to do with clientside muting" but there's two lines dealing with it in the code you pasted. The clientside muting code was added because people requested it. Any plugin that used overrides would ignore the client's mutes.

If you know how to reproduce your problem, please let us know.
Fyren is offline
kossolax
AlliedModders Donor
Join Date: Jan 2008
Location: Belgium
Old 02-02-2011 , 19:10   Re: SetListenOverride Issues
Reply With Quote #10

Run this on a full 40 slots server, with player talking.
Will crash within 30minutes.


PHP Code:
#pragma semicolon 1

#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <cstrike>

#define MAX_AREA_DIST    500

public Plugin:myinfo =  {
    
name "Local-Talk",
    
author "KoSSoLaX",
    
description "LocalTalk based from Voice Proximity Plugin",
    
version "1.2b",
    
url "blabla"
}

new 
g_bIsConnected[65];

public 
OnPluginStart() {
    
//
    
CreateTimer(0.1Timer_UpdateListeners_TIMER_REPEAT);
    
//
}
public 
OnClientDisconnect(client) {
    
g_bIsConnected[client] = false;
}
public 
OnClientPostAdminCheck(client) {
    
g_bIsConnected[client] = true;
}
//
//
// Voice Proximity Plugin
//
public Action:Timer_UpdateListeners(Handle:timer) {
    for (new 
client 1client<=GetMaxClients(); client++) {
        if(!
IsValidClient(client)) {
            continue;
        }
        
        if( 
IsPlayerAlive(client) ) {
            
check_area(client);
        }
        else {
            
check_dead(client);
        }
    }
}

public 
check_area(client)  {
    
    if( !
IsValidClient(client) )
        return;
    
    for (new 
id 1id <= GetMaxClients() ; id++) {
        
        if( !
IsValidClient(id) )
            continue;
        if( 
id == client )
            continue;
        
        if(
entity_distance_stock(clientid) <= MAX_AREA_DIST && IsPlayerAlive(id) ) {    
            
//In Range
            
SetListenOverride(clientidListen_Yes);
        }
        else {
            
//Out of Range
            
SetListenOverride(clientidListen_No);
        }
    }
}

public 
check_dead(client) {
    
    if( !
IsValidClient(client) )
        return;
    
    for (new 
id 1id <= GetMaxClients() ; id++) {
        
        if( !
IsValidClient(id) )
            continue;
        if( 
id == client 
            continue;
        
        
SetListenOverride(clientidListen_No);
    }
}

public 
set_all_listening(client) {
    
    for (new 
id 1id <= GetMaxClients(); id++) {
        
        if( !
IsValidClient(client) || !IsValidClient(id) ) 
            continue;
        if( 
id == client )
            continue;
        
        
SetListenOverride(clientidListen_Yes);
    }
}

public 
Float:entity_distance_stock(ent1ent2) {
    new 
Float:orig1[3];
    new 
Float:orig2[3];
 
    
GetEntPropVector(ent1Prop_Send"m_vecOrigin"orig1);
    
GetEntPropVector(ent2Prop_Send"m_vecOrigin"orig2);

    return 
GetVectorDistance(orig1orig2);
}
public 
bool:IsValidClient(client) {
    if( 
client <= )
        return 
false;
    
    if( 
client GetMaxClients() )
        return 
false;
    
    if( !
IsValidEdict(client) )
        return 
false;
    
    if( !
IsClientConnected(client) )
        return 
false;
    
    if( !
IsClientInGame(client) )
        return 
false;
    
    if( !
IsClientAuthorized(client) )
        return 
false;
    
    if( !
g_bIsConnected[client] )
        return 
false;
    
    return 
true;

kossolax is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 00:52.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode