Update torchlight_changes_unloze/torchlight3/Torchlight/AudioManager.py

This commit is contained in:
Metroid_Skittles 2026-02-07 07:32:39 +01:00
parent 8dc0e15159
commit 28fb9d96d8

View File

@ -2,7 +2,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging import logging
import sys import sys
import io
import math import math
import time import time
from .FFmpegAudioPlayer import FFmpegAudioPlayerFactory from .FFmpegAudioPlayer import FFmpegAudioPlayerFactory
@ -23,6 +22,7 @@ class AudioPlayerFactory():
def NewPlayer(self, _type): def NewPlayer(self, _type):
if _type == self.AUDIOPLAYER_FFMPEG: if _type == self.AUDIOPLAYER_FFMPEG:
return self.FFmpegAudioPlayerFactory.NewPlayer() return self.FFmpegAudioPlayerFactory.NewPlayer()
raise ValueError("Unsupported audio player type: {0}".format(_type))
class AntiSpam(): class AntiSpam():
@ -45,36 +45,37 @@ class AntiSpam():
return True return True
def SpamCheck(self, Delta): def SpamCheck(self):
Now = self.Torchlight().Master.Loop.time() Now = self.Torchlight().Master.Loop.time()
Duration = 0.0 Duration = 0.0
config = self.Torchlight().Config["AntiSpam"]
for Key, Clip in list(self.LastClips.items()): for Key, Clip in list(self.LastClips.items()):
if not Clip["timestamp"]: if not Clip["timestamp"]:
continue continue
if Clip["timestamp"] + Clip["duration"] + self.Torchlight().Config["AntiSpam"]["MaxUsageSpan"] < Now: if Clip["timestamp"] + Clip["duration"] + config["MaxUsageSpan"] < Now:
if not Clip["active"]: if not Clip["active"]:
del self.LastClips[Key] del self.LastClips[Key]
continue continue
Duration += Clip["duration"] Duration += Clip["duration"]
if Duration > self.Torchlight().Config["AntiSpam"]["MaxUsageTime"]: if Duration > config["MaxUsageTime"]:
self.DisabledTime = self.Torchlight().Master.Loop.time() + self.Torchlight().Config["AntiSpam"]["PunishDelay"] self.DisabledTime = self.Torchlight().Master.Loop.time() + config["PunishDelay"]
self.Torchlight().SayChat("Blocked voice commands for the next {0} seconds. Used {1} seconds within {2} seconds.".format( self.Torchlight().SayChat("Blocked voice commands for the next {0} seconds. Used {1} seconds within {2} seconds.".format(
self.Torchlight().Config["AntiSpam"]["PunishDelay"], self.Torchlight().Config["AntiSpam"]["MaxUsageTime"], self.Torchlight().Config["AntiSpam"]["MaxUsageSpan"])) config["PunishDelay"], config["MaxUsageTime"], config["MaxUsageSpan"]))
# Make a copy of the list since AudioClip.Stop() will change the list # Make a copy of the list since AudioClip.Stop() will change the list
for AudioClip in self.Master.AudioClips[:]: for AudioClip in self.Master.AudioClips[:]:
if AudioClip.Level < self.Torchlight().Config["AntiSpam"]["ImmunityLevel"]: if AudioClip.Level < config["ImmunityLevel"]:
AudioClip.Stop() AudioClip.Stop()
self.LastClips.clear() self.LastClips.clear()
def OnPlay(self, clip): def OnPlay(self, clip):
Now = self.Torchlight().Master.Loop.time() Now = self.Torchlight().Master.Loop.time()
self.LastClips[hash(clip)] = dict({"timestamp": Now, "duration": 0.0, "dominant": False, "active": True}) self.LastClips[clip] = dict({"timestamp": Now, "duration": 0.0, "dominant": False, "active": True})
HasDominant = False HasDominant = False
for Key, Clip in self.LastClips.items(): for Key, Clip in self.LastClips.items():
@ -82,40 +83,39 @@ class AntiSpam():
HasDominant = True HasDominant = True
break break
self.LastClips[hash(clip)]["dominant"] = not HasDominant self.LastClips[clip]["dominant"] = not HasDominant
def OnStop(self, clip): def OnStop(self, clip):
if hash(clip) not in self.LastClips: if clip not in self.LastClips:
return return
self.LastClips[hash(clip)]["active"] = False self.LastClips[clip]["active"] = False
if self.LastClips[hash(clip)]["dominant"]: if self.LastClips[clip]["dominant"]:
for Key, Clip in self.LastClips.items(): for Key, Clip in self.LastClips.items():
if Clip["active"]: if Clip["active"]:
Clip["dominant"] = True Clip["dominant"] = True
break break
self.LastClips[hash(clip)]["dominant"] = False self.LastClips[clip]["dominant"] = False
def OnUpdate(self, clip, old_position, new_position): def OnUpdate(self, clip, old_position, new_position):
Delta = new_position - old_position Delta = max(0.0, new_position - old_position)
clip_key = hash(clip) if clip not in self.LastClips:
if clip_key not in self.LastClips:
if self.Logger.isEnabledFor(logging.DEBUG): if self.Logger.isEnabledFor(logging.DEBUG):
self.Logger.debug( self.Logger.debug(
"OnUpdate called for unknown clip key %r; %d known keys", "OnUpdate called for unknown clip key %r; %d known keys",
clip_key, clip,
len(self.LastClips), len(self.LastClips),
) )
return return
Clip = self.LastClips[clip_key] Clip = self.LastClips[clip]
if not Clip["dominant"]: if Delta <= 0.0 or not Clip["dominant"]:
return return
Clip["duration"] += Delta Clip["duration"] += Delta
self.SpamCheck(Delta) self.SpamCheck()
class Advertiser(): class Advertiser():
@ -126,31 +126,32 @@ class Advertiser():
self.LastClips = dict() self.LastClips = dict()
def Think(self, Delta, clip, clip_key): def Think(self, clip):
Now = self.Torchlight().Master.Loop.time() Now = self.Torchlight().Master.Loop.time()
config = self.Torchlight().Config["Advertiser"]
for Key, Clip in list(self.LastClips.items()): for Key, Clip in list(self.LastClips.items()):
if not Clip["timestamp"]: if not Clip["timestamp"]:
continue continue
if Clip["timestamp"] + Clip["duration"] + self.Torchlight().Config["Advertiser"]["MaxSpan"] < Now: if Clip["timestamp"] + Clip["duration"] + config["MaxSpan"] < Now:
if not Clip["active"]: if not Clip["active"]:
del self.LastClips[Key] del self.LastClips[Key]
continue continue
Clip = self.LastClips.get(clip_key) Clip = self.LastClips.get(clip)
if not Clip: if not Clip:
return return
if not clip.StopHinted and not Clip.get("hinted") and Clip["duration"] >= self.Torchlight().Config["Advertiser"]["AdStop"]: if not clip.StopHinted and not Clip.get("hinted") and Clip["duration"] >= config["AdStop"]:
self.Torchlight().SayChat("Hint: Type \x07FF0000!stop(ze) !pls(mg)\x01 to stop all currently playing sounds.") self.Torchlight().SayChat("Hint: Type \x07FF0000!stop(ze) !pls(mg)\x01 to stop all currently playing sounds.")
Clip["hinted"] = True Clip["hinted"] = True
clip.StopHinted = True clip.StopHinted = True
def OnPlay(self, clip): def OnPlay(self, clip):
Now = self.Torchlight().Master.Loop.time() Now = self.Torchlight().Master.Loop.time()
self.LastClips[hash(clip)] = dict({"timestamp": Now, "duration": 0.0, "dominant": False, "active": True, "hinted": False}) self.LastClips[clip] = dict({"timestamp": Now, "duration": 0.0, "dominant": False, "active": True, "hinted": False})
HasDominant = False HasDominant = False
for Key, Clip in self.LastClips.items(): for Key, Clip in self.LastClips.items():
@ -158,34 +159,33 @@ class Advertiser():
HasDominant = True HasDominant = True
break break
self.LastClips[hash(clip)]["dominant"] = not HasDominant self.LastClips[clip]["dominant"] = not HasDominant
def OnStop(self, clip): def OnStop(self, clip):
if hash(clip) not in self.LastClips: if clip not in self.LastClips:
return return
self.LastClips[hash(clip)]["active"] = False self.LastClips[clip]["active"] = False
if self.LastClips[hash(clip)]["dominant"]: if self.LastClips[clip]["dominant"]:
for Key, Clip in self.LastClips.items(): for Key, Clip in self.LastClips.items():
if Clip["active"]: if Clip["active"]:
Clip["dominant"] = True Clip["dominant"] = True
break break
self.LastClips[hash(clip)]["dominant"] = False self.LastClips[clip]["dominant"] = False
def OnUpdate(self, clip, old_position, new_position): def OnUpdate(self, clip, old_position, new_position):
Delta = new_position - old_position Delta = max(0.0, new_position - old_position)
clip_key = hash(clip) if clip not in self.LastClips:
if clip_key not in self.LastClips:
return return
Clip = self.LastClips[clip_key] Clip = self.LastClips[clip]
if not Clip["dominant"]: if Delta <= 0.0 or not Clip["dominant"]:
return return
Clip["duration"] += Delta Clip["duration"] += Delta
self.Think(Delta, clip, clip_key) self.Think(clip)
class AudioManager(): class AudioManager():
@ -205,21 +205,23 @@ class AudioManager():
if player.Access: if player.Access:
Level = player.Access["level"] Level = player.Access["level"]
if str(Level) in self.Torchlight().Config["AudioLimits"]: config = self.Torchlight().Config["AudioLimits"]
if self.Torchlight().Config["AudioLimits"][str(Level)]["Uses"] >= 0 and \ if str(Level) in config:
player.Storage["Audio"]["Uses"] >= self.Torchlight().Config["AudioLimits"][str(Level)]["Uses"]: level_config = config[str(Level)]
if level_config["Uses"] >= 0 and \
player.Storage["Audio"]["Uses"] >= level_config["Uses"]:
self.Torchlight().SayPrivate(player, "You have used up all of your free uses! ({0} uses)".format( self.Torchlight().SayPrivate(player, "You have used up all of your free uses! ({0} uses)".format(
self.Torchlight().Config["AudioLimits"][str(Level)]["Uses"])) level_config["Uses"]))
return False return False
if player.Storage["Audio"]["TimeUsed"] >= self.Torchlight().Config["AudioLimits"][str(Level)]["TotalTime"]: if player.Storage["Audio"]["TimeUsed"] >= level_config["TotalTime"]:
self.Torchlight().SayPrivate(player, "You have used up all of your free time! ({0} seconds)".format( self.Torchlight().SayPrivate(player, "You have used up all of your free time! ({0} seconds)".format(
self.Torchlight().Config["AudioLimits"][str(Level)]["TotalTime"])) level_config["TotalTime"]))
return False return False
TimeElapsed = self.Torchlight().Master.Loop.time() - player.Storage["Audio"]["LastUse"] TimeElapsed = self.Torchlight().Master.Loop.time() - player.Storage["Audio"]["LastUse"]
UseDelay = player.Storage["Audio"]["LastUseLength"] * self.Torchlight().Config["AudioLimits"][str(Level)]["DelayFactor"] UseDelay = player.Storage["Audio"]["LastUseLength"] * level_config["DelayFactor"]
if TimeElapsed < UseDelay: if TimeElapsed < UseDelay:
self.Torchlight().SayPrivate(player, "You are currently on cooldown! ({0} seconds left)".format( self.Torchlight().SayPrivate(player, "You are currently on cooldown! ({0} seconds left)".format(
@ -253,7 +255,7 @@ class AudioManager():
if player != AudioClip.Player: if player != AudioClip.Player:
self.Torchlight().SayPrivate(player, "Stopped \"{0}\"({1}) audio clip.".format(AudioClip.Player.Name, AudioClip.Player.UserID)) self.Torchlight().SayPrivate(player, "Stopped \"{0}\"({1}) audio clip.".format(AudioClip.Player.Name, AudioClip.Player.UserID))
def AudioClip(self, player, uri, _type = AudioPlayerFactory.AUDIOPLAYER_FFMPEG): def CreateAudioClip(self, player, uri, _type = AudioPlayerFactory.AUDIOPLAYER_FFMPEG):
Level = 0 Level = 0
if player.Access: if player.Access:
Level = player.Access["level"] Level = player.Access["level"]
@ -282,6 +284,9 @@ class AudioManager():
return Clip return Clip
def AudioClip(self, player, uri, _type = AudioPlayerFactory.AUDIOPLAYER_FFMPEG):
return self.CreateAudioClip(player, uri, _type)
def OnDisconnect(self, player): def OnDisconnect(self, player):
for AudioClip in self.AudioClips[:]: for AudioClip in self.AudioClips[:]:
if AudioClip.Player == player: if AudioClip.Player == player:
@ -362,9 +367,12 @@ class AudioClip():
del self.AudioPlayer del self.AudioPlayer
def OnUpdate(self, old_position, new_position): def OnUpdate(self, old_position, new_position):
Delta = new_position - old_position Delta = max(0.0, new_position - old_position)
self.LastPosition = new_position self.LastPosition = new_position
if Delta <= 0.0:
return
self.Player.Storage["Audio"]["TimeUsed"] += Delta self.Player.Storage["Audio"]["TimeUsed"] += Delta
self.Player.Storage["Audio"]["LastUseLength"] += Delta self.Player.Storage["Audio"]["LastUseLength"] += Delta