Im lost trying to get found in an ocean of codes

This commit is contained in:
MyNameIsBatman 2021-12-04 21:30:45 -03:00
parent 32bb662ac1
commit d87a059c58
13 changed files with 815 additions and 19 deletions

View File

@ -33,6 +33,7 @@ import { IRoomSessionManager } from './session/IRoomSessionManager';
import { ISessionDataManager } from './session/ISessionDataManager'; import { ISessionDataManager } from './session/ISessionDataManager';
import { RoomSessionManager } from './session/RoomSessionManager'; import { RoomSessionManager } from './session/RoomSessionManager';
import { SessionDataManager } from './session/SessionDataManager'; import { SessionDataManager } from './session/SessionDataManager';
import { ISoundManager } from './sound/ISoundManager';
import { SoundManager } from './sound/SoundManager'; import { SoundManager } from './sound/SoundManager';
import { HabboWebTools } from './utils/HabboWebTools'; import { HabboWebTools } from './utils/HabboWebTools';
@ -98,6 +99,7 @@ export class Nitro extends Application implements INitro
if(this._worker) this._worker.onmessage = this.createWorkerEvent.bind(this); if(this._worker) this._worker.onmessage = this.createWorkerEvent.bind(this);
} }
soundManager: ISoundManager;
public static bootstrap(): void public static bootstrap(): void
{ {

View File

@ -0,0 +1,7 @@
import { INitroManager } from '../../core/common/INitroManager';
import { IMusicManager } from './music/IMusicManager';
export interface ISoundManager extends INitroManager
{
musicManager: IMusicManager;
}

View File

@ -2,8 +2,11 @@ import { AdvancedMap, Nitro, NitroSettingsEvent, RoomEngineEvent, RoomEngineObje
import { NitroManager } from '../../core/common/NitroManager'; import { NitroManager } from '../../core/common/NitroManager';
import { NitroSoundEvent } from '../events/NitroSoundEvent'; import { NitroSoundEvent } from '../events/NitroSoundEvent';
import { NitroEvent } from './../../core/events/NitroEvent'; import { NitroEvent } from './../../core/events/NitroEvent';
import { ISoundManager } from './ISoundManager';
import { IMusicManager } from './music/IMusicManager';
import { MusicManager } from './music/MusicManager';
export class SoundManager extends NitroManager export class SoundManager extends NitroManager implements ISoundManager
{ {
private _volumeSystem: number; private _volumeSystem: number;
private _volumeFurni: number; private _volumeFurni: number;
@ -13,6 +16,8 @@ export class SoundManager extends NitroManager
private _furniSamples: AdvancedMap<number, HTMLAudioElement>; private _furniSamples: AdvancedMap<number, HTMLAudioElement>;
private _furnitureBeingPlayed: AdvancedMap<number, number>; private _furnitureBeingPlayed: AdvancedMap<number, number>;
private _musicManager: MusicManager;
constructor() constructor()
{ {
super(); super();
@ -25,9 +30,37 @@ export class SoundManager extends NitroManager
this._furniSamples = new AdvancedMap(); this._furniSamples = new AdvancedMap();
this._furnitureBeingPlayed = new AdvancedMap(); this._furnitureBeingPlayed = new AdvancedMap();
this._musicManager = new MusicManager();
this.onEvent = this.onEvent.bind(this); this.onEvent = this.onEvent.bind(this);
} }
public onInit(): void
{
this._musicManager.init();
Nitro.instance.roomEngine.events.addEventListener(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomEngineObjectEvent.REMOVED, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomEngineEvent.DISPOSED, this.onEvent);
Nitro.instance.events.addEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onEvent);
Nitro.instance.events.addEventListener(NitroSoundEvent.PLAY_SOUND, this.onEvent);
}
public onDispose(): void
{
if(this._musicManager)
{
this._musicManager.dispose();
this._musicManager = null;
}
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineObjectEvent.REMOVED, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineEvent.DISPOSED, this.onEvent);
Nitro.instance.events.removeEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onEvent);
Nitro.instance.events.removeEventListener(NitroSoundEvent.PLAY_SOUND, this.onEvent);
}
private onEvent(event: NitroEvent) private onEvent(event: NitroEvent)
{ {
switch(event.type) switch(event.type)
@ -72,24 +105,6 @@ export class SoundManager extends NitroManager
} }
} }
public onInit(): void
{
Nitro.instance.roomEngine.events.addEventListener(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomEngineObjectEvent.REMOVED, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomEngineEvent.DISPOSED, this.onEvent);
Nitro.instance.events.addEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onEvent);
Nitro.instance.events.addEventListener(NitroSoundEvent.PLAY_SOUND, this.onEvent);
}
public onDispose(): void
{
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineObjectEvent.REMOVED, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomEngineEvent.DISPOSED, this.onEvent);
Nitro.instance.events.removeEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onEvent);
Nitro.instance.events.removeEventListener(NitroSoundEvent.PLAY_SOUND, this.onEvent);
}
private playSample(sample: HTMLAudioElement, volume: number, pitch: number = 1): void private playSample(sample: HTMLAudioElement, volume: number, pitch: number = 1): void
{ {
sample.volume = volume; sample.volume = volume;
@ -205,4 +220,9 @@ export class SoundManager extends NitroManager
sample.volume = volume; sample.volume = volume;
}); });
} }
public get musicManager(): IMusicManager
{
return this._musicManager;
}
} }

View File

@ -0,0 +1,53 @@
import { Nitro } from './../../Nitro';
export class SongStartRequestData
{
private _songId: number;
private _startPos: number;
private _playLength: number;
private _playRequestTime: number;
private _fadeInSeconds: number;
private _fadeOutSeconds: number;
constructor(songId: number, startPos: number, playLength: number, playRequestTime: number, fadeInSeconds: number, fadeOutSeconds: number)
{
this._songId = songId;
this._startPos = startPos;
this._playLength = playLength;
this._playRequestTime = playRequestTime;
this._fadeInSeconds = fadeInSeconds;
this._fadeOutSeconds = fadeOutSeconds;
}
public get songId(): number
{
return this._songId;
}
public get startPos(): number
{
if(this._startPos < 0) return 0;
return this._startPos + ((Nitro.instance.time - this._playRequestTime) / 1000);
}
public get playLength(): number
{
return this._playLength;
}
public get playRequestTime(): number
{
return this._playRequestTime;
}
public get fadeInSeconds(): number
{
return this._fadeInSeconds;
}
public get fadeOutSeconds(): number
{
return this._fadeOutSeconds;
}
}

View File

@ -0,0 +1,22 @@
import { TraxChannelItem } from './TraxChannelItem';
export class TraxChannel
{
private _id: number;
private _items: TraxChannelItem[];
constructor(id: number)
{
this._id = id;
this._items = [];
}
public addChannelItem(item: TraxChannelItem): void
{
this._items.push(item);
}
public get items(): TraxChannelItem[]
{
return this._items;
}
}

View File

@ -0,0 +1,21 @@
export class TraxChannelItem
{
private _id: number;
private _length: number;
constructor(id: number, length: number)
{
this._id = id;
this._length = length;
}
public get id(): number
{
return this._id;
}
public get length(): number
{
return this._length;
}
}

View File

@ -0,0 +1,94 @@
import { TraxChannel } from './TraxChannel';
import { TraxChannelItem } from './TraxChannelItem';
export class TraxData
{
private _channels: TraxChannel[];
private _metaData: Map<string, string>;
constructor(data: string)
{
this._channels = [];
let channelLines: string[] = [];
const lines: string[] = data.split(':');
const lastLine: string = lines[lines.length - 1];
if(lastLine.indexOf('meta') > -1)
{
const metaData: string[] = lastLine.split(';');
for(const meta of metaData)
{
const metaAttributes: string[] = meta.split(',');
this._metaData.set(metaAttributes[0], metaAttributes[1]);
}
channelLines = lines.slice(0, lines.length - 1);
}
else
{
channelLines = lines;
}
for(let i = 0; i < channelLines.length / 2; i++)
{
if(channelLines[i * 2].length > 0)
{
const channelId: number = parseInt(channelLines[i * 2]);
const channelItemSets: string[] = channelLines[(i * 2) + 1].split(';');
const channel: TraxChannel = new TraxChannel(channelId);
for(const channelItemSet of channelItemSets)
{
const channelItemData: string[] = channelItemSet.split(',');
if(channelItemData.length !== 2) return;
channel.addChannelItem(new TraxChannelItem(parseInt(channelItemData[0]), parseInt(channelItemData[1])));
}
this._channels.push(channel);
}
}
}
public get channels(): TraxChannel[]
{
return this._channels;
}
public getSampleIds(): number[]
{
const ids: number[] = [];
for(const channel of this._channels)
{
for(const item of channel.items)
{
if(ids.indexOf(item.id) === -1) ids.push(item.id);
}
}
return ids;
}
public get hasMetaData(): boolean
{
return this._metaData.get('meta') !== null;
}
public get metaCutMode(): boolean
{
return this._metaData.get('c') !== null;
}
public get metaTempo(): number
{
const tempo: string = this._metaData.get('t');
if(!tempo) return null;
return parseInt(tempo);
}
}

View File

@ -0,0 +1,195 @@
import { BinaryWriter } from '../../../core/communication/codec/BinaryWriter';
import { BinaryReader } from './../../../core/communication/codec/BinaryReader';
export class TraxSample
{
public static readonly SAMPLE_FREQUENCY_44KHZ: string = 'sample_44khz';
public static readonly SAMPLE_FREQUENCY_22KHZ: string = 'sample_22khz';
public static readonly SAMPLE_FREQUENCY_11KHZ: string = 'sample_11khz';
public static readonly SAMPLE_SCALE_16BIT: string = 'sample_16bit';
public static readonly SAMPLE_SCALE_8BIT: string = 'sample_8bit';
public static readonly _Str_11575: number = (1 / 0x8000);
private static readonly _Str_14308: number = 32;
private static readonly MASK_8BIT: number = 0xFF;
private static readonly MASK_16BIT: number = 0xFFFF;
private static readonly OFFSET_8BIT: number = 127;
private static readonly OFFSET_16BIT: number = 32767;
private _sampleData: number[];
private _id: number;
private _samplesPerValue: number;
private _sampleRepeats: number;
private _usageList: any[];
private _usageTimestamp: number;
constructor(k: BinaryWriter, sampleId: number, sampleFrequency: string = TraxSample.SAMPLE_FREQUENCY_44KHZ, sampleScale: string = TraxSample.SAMPLE_SCALE_16BIT)
{
this._id = sampleId;
this._samplesPerValue = 2;
this._sampleRepeats = 1;
let local5 = 65536;
switch(sampleFrequency)
{
case TraxSample.SAMPLE_FREQUENCY_22KHZ:
this._sampleRepeats = 2;
break;
case TraxSample.SAMPLE_FREQUENCY_11KHZ:
this._sampleRepeats = 4;
break;
default:
this._sampleRepeats = 1;
}
if(sampleScale === TraxSample.SAMPLE_SCALE_8BIT)
{
this._samplesPerValue = 4;
local5 = 0x0100;
}
const local6: number = this._samplesPerValue * this._sampleRepeats;
const local7: number = (Math.trunc(k.getBuffer().byteLength / 8) / local6) * local6;
this._sampleData = new Array(local7/local6);
const local8: number = 1 / (local5 / 2);
k.position = 0;
const reader: BinaryReader = new BinaryReader(k.getBuffer());
let local9: number;
const local10: number = (local7 / this._sampleRepeats);
let local12: number;
let local15: number;
for(let i = 0; i < local10; i++)
{
local12 = reader.readFloat();
reader.readFloat();
for(let j = 2; j <= this._sampleRepeats; j++)
{
local15 = reader.readFloat();
reader.readFloat();
local12 = (((j * (j - 1)) / j) + (local15 / j));
}
if(i >= ((local10 - 1) - TraxSample._Str_14308)) local12 = (local12 * (((local10 - 1) - 1) / TraxSample._Str_14308));
let local14 = ((local12 + 1) / local8);
if(local14 < 0)
{
local14 = 0;
}
else if(local14 >= local5)
{
local14 = local5 - 1;
}
local9 = (local9 * local5) + local14;
if((i % this._samplesPerValue) === this._samplesPerValue - 1)
{
this._sampleData[Math.trunc(i / this._samplesPerValue)] = local9;
}
}
}
public setSample(k: number[], arg2: number, arg3: number, arg4: number): number
{
let local8: number;
let local9: number;
let local10: number;
if(k === null || this._sampleData === null) return arg4;
const local5 = this._samplesPerValue * this._sampleRepeats;
arg4 = arg4 / local5;
if(arg2 < 0) arg3 = arg3 + arg2;
if(arg3 > k.length - arg2) arg3 = k.length - arg2;
let local6 = arg3 / local5;
let local7: number;
if(local6 > this._sampleData.length - arg4)
{
local7 = (local6 - this._sampleData.length - arg4) * local5;
local6 = this._sampleData.length - arg4;
if(local7 > (k.length - arg2)) local7 = k.length - arg2;
}
if(this._sampleRepeats === 1)
{
if(this._samplesPerValue === 2)
{
while(local6-- > 0)
{
local8 = this._sampleData[arg4++];
k[arg2++] = (((local8 >> 16) & TraxSample.MASK_16BIT) - TraxSample.OFFSET_16BIT);
k[arg2++] = ((local8 & TraxSample.MASK_16BIT) - TraxSample.OFFSET_16BIT);
}
}
else if(this._samplesPerValue === 4)
{
while(local6-- > 0)
{
local8 = this._sampleData[arg4++];
k[arg2++] = ((((local8 >> 24) & TraxSample.MASK_8BIT) - TraxSample.OFFSET_8BIT) << 8);
k[arg2++] = ((((local8 >> 16) & TraxSample.MASK_8BIT) - TraxSample.OFFSET_8BIT) << 8);
k[arg2++] = ((((local8 >> 8) & TraxSample.MASK_8BIT) - TraxSample.OFFSET_8BIT) << 8);
k[arg2++] = (((local8 & TraxSample.MASK_8BIT) - TraxSample.OFFSET_8BIT) << 8);
}
}
}
else if(this._sampleRepeats >= 2)
{
local9 = 0;
local10 = 0;
if(this._samplesPerValue === 2)
{
while(local6-- > 0)
{
local8 = this._sampleData[arg4++];
local10 = (((local8 >> 16) & TraxSample.MASK_16BIT) - TraxSample.OFFSET_16BIT);
local9 = this._sampleRepeats;
while(local9 > 0)
// eslint-disable-next-line no-empty
{
}
}
}
}
}
public get id(): number
{
return this._id;
}
public get length(): number
{
return this._sampleData.length * this._samplesPerValue * this._sampleRepeats;
}
public get usageCount(): number
{
return this._usageList.length;
}
public get usageTimestamp(): number
{
return this._usageTimestamp;
}
}

View File

@ -0,0 +1,166 @@
import { TraxData } from './TraxData';
export class TraxSequencer
{
private static readonly SAMPLES_PER_SECOND: number = 44100;
private static readonly BUFFER_LENGTH: number = 0x2000;
private static readonly SAMPLES_BAR_LENGTH: number = 88000;
private static readonly BAR_LENGTH: number = 88000;
private static readonly MIXING_BUFFER: number[] = new Array(this.BUFFER_LENGTH);
private static readonly INTERPOLATION_BUFFER: number[] = new Array(this.BUFFER_LENGTH);
private _volume: number;
//sound
//soundChannel
private _traxData: TraxData;
private _samples: Map<number, any>;
private _ready: boolean;
private _songId: number;
private _playLengthSamples: number = 0;
private _playHead: number;
//sequence array
private _prepared: boolean;
private _finished: boolean = true;
private _lengthSamples: number;
private _latencyMs: number;
private _fadeInActive: boolean;
private _fadeOutActive: boolean;
private _fadeInLengthSamples: number;
private _fadeOutLengthSamples: number;
private _fadeInSampleCounter: number;
private _fadeOutSampleCounter: number;
//fadeOutStopTimer
//stopTimer
private _useCutMode: boolean;
private _expectedStreamPosition: number = 0;
private _bufferUnderRunCount: number = 0;
constructor(songId: number, traxData: TraxData, samples: any)
{
this._latencyMs = 30;
//set events
this._songId = songId;
this._volume = 1;
//set sound new Sound()
//set soundchannel null
this._samples = new Map();
this._traxData = traxData;
this._ready = true;
this._playHead = 0;
//set sequence []
this._prepared = false;
this._lengthSamples = 0;
this._finished = false;
this._fadeInActive = false;
this._fadeOutActive = false;
this._fadeInLengthSamples = 0;
this._fadeOutLengthSamples = 0;
this._fadeInSampleCounter = 0;
this._fadeOutSampleCounter = 0;
}
public prepare(): boolean
{
if(!this._ready) return false;
if(this._prepared) return true;
if(this._traxData != null)
{
this._useCutMode = false;
if(this._traxData.hasMetaData)
{
this._useCutMode = this._traxData.metaCutMode;
}
if(this._useCutMode)
// eslint-disable-next-line no-empty
{
}
}
}
public prepareSequence(): void
{
for(const channel of this._traxData.channels)
{
for(const item of channel.items)
{
const sample = this._samples.get(item.id);
}
}
}
public get position(): number
{
return this._playHead / TraxSequencer.SAMPLES_PER_SECOND;
}
private set position(value: number)
{
this._playHead = value * TraxSequencer.SAMPLES_PER_SECOND;
}
public get volume(): number
{
return this._volume;
}
public set volume(value: number)
{
this._volume = value;
//soundTransform for channel
}
public get ready(): boolean
{
return this._ready;
}
public set ready(value: boolean)
{
this._ready = value;
}
public get finished(): boolean
{
return this._finished;
}
public set finished(value: boolean)
{
this._finished = value;
}
public get fadeOutSeconds(): number
{
return this._fadeOutLengthSamples / TraxSequencer.SAMPLES_PER_SECOND;
}
public set fadeOutSeconds(value: number)
{
this._fadeOutLengthSamples = value * TraxSequencer.SAMPLES_PER_SECOND;
}
public get fadeInSetconds(): number
{
return this._fadeInLengthSamples / TraxSequencer.SAMPLES_PER_SECOND;
}
public set fadeInSeconds(value: number)
{
this._fadeInLengthSamples = value * TraxSequencer.SAMPLES_PER_SECOND;
}
public get traxData(): TraxData
{
return this._traxData;
}
public get length(): number
{
return this._lengthSamples / TraxSequencer.SAMPLES_PER_SECOND;
}
}

View File

@ -0,0 +1,11 @@
import { NitroEvent } from '../../../core/events/NitroEvent';
export class SoundManagerEvent extends NitroEvent
{
public static TRAX_SONG_COMPLETE: string = 'SME_TRAX_SONG_COMPLETE';
constructor(type: string)
{
super(type);
}
}

View File

@ -0,0 +1,7 @@
import { INitroManager } from '../../../core/common/INitroManager';
export interface IMusicManager extends INitroManager
{
playPosition: number;
}

View File

@ -0,0 +1,190 @@
import { NitroManager } from '../../../core/common/NitroManager';
import { NitroEvent } from '../../../core/events/NitroEvent';
import { JukeboxPlayListFullMessageEvent } from '../../communication/messages/incoming/sound/JukeboxPlayListFullMessageEvent';
import { JukeboxSongDisksMessageEvent } from '../../communication/messages/incoming/sound/JukeboxSongDisksMessageEvent';
import { NowPlayingMessageEvent } from '../../communication/messages/incoming/sound/NowPlayingMessageEvent';
import { TraxSongInfoMessageEvent } from '../../communication/messages/incoming/sound/TraxSongInfoMessageEvent';
import { UserSongDisksInventoryMessageEvent } from '../../communication/messages/incoming/sound/UserSongDisksInventoryMessageEvent';
import { GetSongInfoMessageComposer } from '../../communication/messages/outgoing/sound/GetSongInfoMessageComposer';
import { Nitro } from '../../Nitro';
import { RoomObjectSoundMachineEvent } from '../../room/events/RoomObjectSoundMachineEvent';
import { SongStartRequestData } from '../common/SongStartRequestData';
import { SoundManagerEvent } from '../events/SoundManagerEvent';
import { SongInfoEntry } from './../../communication/messages/incoming/sound/SongInfoEntry';
import { IMusicManager } from './IMusicManager';
import { MusicPriorities } from './MusicPriorities';
export class MusicManager extends NitroManager implements IMusicManager
{
public static readonly SKIP_POSITION_SET: number = -1;
private static readonly MAXIMUM_NOTIFY_PRIORITY: number = MusicPriorities.PRIORITY_ROOM_PLAYLIST;
private _timerInstance: any;
private _songRequestList: number[];
private _requestedSongs: Map<number, boolean>;
private _availableSongs: Map<number, SongInfoEntry>;
private _songRequestsPerPriority: SongStartRequestData[];
private _currentEntryId: number;
private _playPosition: number;
private _isPlaying: boolean;
constructor()
{
super();
this._timerInstance = null;
this._songRequestList = [];
this._requestedSongs = new Map();
this._availableSongs = new Map();
this._songRequestsPerPriority = [];
this._currentEntryId = -1;
this._playPosition = -1;
this._isPlaying = false;
this.onEvent = this.onEvent.bind(this);
this._timerInstance = setInterval(this.onTick.bind(this), 1000);
}
public onInit(): void
{
Nitro.instance.communication.connection.addMessageEvent(new TraxSongInfoMessageEvent(this.onEvent));
Nitro.instance.communication.connection.addMessageEvent(new UserSongDisksInventoryMessageEvent(this.onEvent));
Nitro.instance.communication.connection.addMessageEvent(new NowPlayingMessageEvent(this.onNowPlayingMessageEvent.bind(this)));
Nitro.instance.communication.connection.addMessageEvent(new JukeboxSongDisksMessageEvent(this.onEvent));
Nitro.instance.communication.connection.addMessageEvent(new JukeboxPlayListFullMessageEvent(this.onEvent));
Nitro.instance.roomEngine.events.addEventListener(RoomObjectSoundMachineEvent.JUKEBOX_INIT, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomObjectSoundMachineEvent.JUKEBOX_DISPOSE, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_INIT, this.onEvent);
Nitro.instance.roomEngine.events.addEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_DISPOSE, this.onEvent);
this.events.addEventListener(SoundManagerEvent.TRAX_SONG_COMPLETE, this.onEvent);
}
public onDispose(): void
{
if(this._timerInstance)
{
clearInterval(this._timerInstance);
this._timerInstance = null;
}
Nitro.instance.communication.connection.removeMessageEvent(new TraxSongInfoMessageEvent(this.onEvent));
Nitro.instance.communication.connection.removeMessageEvent(new UserSongDisksInventoryMessageEvent(this.onEvent));
Nitro.instance.communication.connection.removeMessageEvent(new NowPlayingMessageEvent(this.onNowPlayingMessageEvent.bind(this)));
Nitro.instance.communication.connection.removeMessageEvent(new JukeboxSongDisksMessageEvent(this.onEvent));
Nitro.instance.communication.connection.removeMessageEvent(new JukeboxPlayListFullMessageEvent(this.onEvent));
Nitro.instance.roomEngine.events.removeEventListener(RoomObjectSoundMachineEvent.JUKEBOX_INIT, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomObjectSoundMachineEvent.JUKEBOX_DISPOSE, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_INIT, this.onEvent);
Nitro.instance.roomEngine.events.removeEventListener(RoomObjectSoundMachineEvent.SOUND_MACHINE_DISPOSE, this.onEvent);
this.events.removeEventListener(SoundManagerEvent.TRAX_SONG_COMPLETE, this.onEvent);
}
private onEvent(event: NitroEvent): void
{
console.log('music manager', event);
}
private onTraxSongInfoMessageEvent(event: TraxSongInfoMessageEvent): void
{
const parser = event.getParser();
for(const song of parser.songs)
{
const songAvailable: boolean = (this._availableSongs.get(song.id) !== null);
const areSamplesRequested: boolean = (this._requestedSongs.get(song.id) !== null);
if(!songAvailable)
{
if(areSamplesRequested)
{
//LoadTraxSong
}
const songInfoEntry: SongInfoEntry = new SongInfoEntry(song.id, song.length, song.name, song.creator, song.data);
this._availableSongs.set(song.id, songInfoEntry);
const topRequestPriotityIndex: number = this.getTopRequestPriority();
const songId: number = this.getSongIdRequestedAtPriority(topRequestPriotityIndex);
}
}
}
private onNowPlayingMessageEvent(event: NowPlayingMessageEvent): void
{
const parser = event.getParser();
this._isPlaying = (parser.currentSongId !== -1);
if(parser.currentSongId >= 0)
{
this.playSong(parser.currentSongId, MusicPriorities.PRIORITY_ROOM_PLAYLIST, (parser.syncCount / 1000), 0, 1, 1);
}
else
{
this.stopPlaying();
}
if(parser.nextSongId >= 0) this.requestSong(parser.nextSongId, true);
this._playPosition = parser.currentPosition;
//Dispatch local event NowPlayingEvent
}
private onTick(): void
{
if(this._songRequestList.length === 0) return;
Nitro.instance.communication.connection.send(new GetSongInfoMessageComposer(...this._songRequestList));
this._songRequestList = [];
}
private requestSong(songId: number, arg2: boolean): void
{
if(this._requestedSongs.get(songId) === null)
{
this._requestedSongs.set(songId, arg2);
this._songRequestList.push(songId);
}
}
private playSong(songId: number, priority: number, startPos: number = 0, playLength: number = 0, fadeInSeconds: number = 0.5, fadeOutSeconds: number = 0.5)
{
}
private stopPlaying(): void
{
this._currentEntryId = -1;
this._playPosition = -1;
this._isPlaying = false;
}
private getTopRequestPriority(): number
{
return this._songRequestsPerPriority.length - 1;
}
private getSongIdRequestedAtPriority(priorityIndex: number): number
{
if(priorityIndex < 0 || priorityIndex >= MusicPriorities.PRIORITY_COUNT) return -1;
if(!this._songRequestsPerPriority[priorityIndex]) return -1;
return this._songRequestsPerPriority[priorityIndex].songId;
}
public get playPosition(): number
{
return this._playPosition;
}
public set playPosition(value: number)
{
this._playPosition = value;
}
}

View File

@ -0,0 +1,8 @@
export class MusicPriorities
{
public static readonly PRIORITY_ROOM_PLAYLIST: number = 0;
public static readonly PRIORITY_USER_PLAYLIST: number = 1;
public static readonly PRIORITY_SONG_PLAY: number = 2;
public static readonly PRIORITY_PURCHASE_PREVIEW: number = 3;
public static readonly PRIORITY_COUNT: number = 4;
}