Server library implementing the Bloop Box protocol. This allows you to implement your own Bloop Server without having to worry about networking details.
Run npm i bloop-server
In order to use the server, you have to implement a processor first. Following is a boilerplate code which should get you started:
import {randomUUID} from 'crypto';
import uuidBuffer from 'uuid-buffer';
import {
AudioFoundResult,
AudioNotFoundResult,
ThrottledUidResult,
UnknownUidResult,
ValidUidResult,
} from 'bloop-server';
import type {
CheckUidResult,
GetAudioResult,
Processor,
} from 'bloop-server';
class MyProcessor implements Processor {
public authenticate(clientId : string, secret : string) : boolean {
return clientId === 'foo' && secret === 'bar';
}
public async checkUid(clientId : string, uid : Buffer) : CheckUidResult {
const hexUid = uid.toString('hex');
if (hexUid === '00000000000001') {
// If the UID was scanned too quickly in succession, return a throttle result.
return new ThrottledUidResult();
}
if (hexUid === '00000000000002') {
// This is a valid UID, return an array of achievement IDs, if any were achieved.
return new ValidUidResult([
uuidBuffer.toBuffer(randomUUID()),
uuidBuffer.toBuffer(randomUUID()),
]);
}
return new UnknownUidResult();
}
public async getAudio(id : Buffer) : GetAudioResult {
const hexId = id.toString('hex');
if (hexId === '0000000000000000000000000000000000000001') {
// Return MP3 audio data.
return new AudioFoundResult(Buffer.alloc(50));
}
return new AudioNotFoundResult();
}
}
Instead of implementing the processor as a class. you can also implement it has a simple object with three arrow
functions attached to it, using Processor
as the object type:
const myProcessor : Processor = {
authenticate: (clientId : string, secret : string) : boolean => {
// …
},
checkUid: async (clientId : string, uid : Buffer) : Promise<CheckUidResult> => {
// …
},
getAudio: async (id : Buffer) : Promise<GetAudioResult> => {
// …
},
};
Note: The
authenticate
method can either be synchronous or markedasync
and return a promise.
After implementing and instantiating your processor, it's time to create the server. For this, you'll first need to have a valid SSL certificate. Then you can go ahead and start the server:
import {startServer} from 'boop-server';
const processor = new MyProcessor();
const {server, closeOpenConnections} = await startServer({
processor,
tls: {
// Buffer or string of your private key.
key: '',
// Buffer or string of your full certificate chain.
cert: '',
},
// Choose a port which is available on your server.
// If not specified, a random port is chosen.
port: 12345,
// Optionally bind the server to a specific interface.
//hostname: '',
// Optionally define a logger to get information from the server.
// See the winston NPM package for more details:
//logger: winston.createLogger({
// format: winston.format.simple(),
// transports: new winston.transport.Console(),
//}),
// Authentication timeout, defaults to 1 second.
//authTimeout: 1_000,
// Idle timeout, defaults to 30 second.
//idleTimeout: 30_000,
});
// This takes care of gracefully shutting down the server on CTRL+C
process.on('SIGINT', () => {
closeOpenConnections();
server.close(() => {
process.exit(0);
});
});