103 lines
3.1 KiB
TypeScript
103 lines
3.1 KiB
TypeScript
import core from '../chat/core';
|
|
import { Character as CharacterFChatInf } from '../fchat';
|
|
import { Character as ComplexCharacter } from '../site/character_page/interfaces';
|
|
import { Matcher } from './matcher';
|
|
import { AdCache } from './ad-cache';
|
|
import { ProfileCacheQueueEntry } from './cache-manager';
|
|
import { TagId } from './matcher-types';
|
|
|
|
|
|
export class CharacterProfiler {
|
|
static readonly ADVERTISEMENT_RECENT_RANGE = 22 * 60 * 1000;
|
|
static readonly ADVERTISEMENT_POTENTIAL_RAGE = 50 * 60 * 1000;
|
|
|
|
protected adCache: AdCache;
|
|
protected me: ComplexCharacter;
|
|
|
|
constructor(me: ComplexCharacter, adCache: AdCache) {
|
|
this.me = me;
|
|
this.adCache = adCache;
|
|
}
|
|
|
|
calculateInterestScoreForQueueEntry(entry: ProfileCacheQueueEntry): number {
|
|
const c = core.characters.get(entry.name);
|
|
|
|
if (!c)
|
|
return 0;
|
|
|
|
const genderScore = this.getInterestScoreForGender(this.me, c);
|
|
const statusScore = this.getInterestScoreForStatus(c);
|
|
const adScore = (genderScore > 0) ? this.getLastAdvertisementStatus(c) : 0;
|
|
const friendlyScore = this.getInterestScoreForFriendlies(c);
|
|
|
|
// tslint:disable-next-line: number-literal-format binary-expression-operand-order
|
|
const score = ((1.0 * genderScore) + (1.0 * statusScore) + (1.0 * adScore) + (1.0 * friendlyScore));
|
|
|
|
// tslint:disable-next-line: number-literal-format binary-expression-operand-order
|
|
return (c.status === 'looking') ? score + 10.0 : score;
|
|
}
|
|
|
|
|
|
getInterestScoreForFriendlies(c: CharacterFChatInf.Character): number {
|
|
if(c.isFriend)
|
|
return 1;
|
|
|
|
if(c.isBookmarked)
|
|
return 0.5;
|
|
|
|
if(c.isIgnored)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
getInterestScoreForGender(me: ComplexCharacter, c: CharacterFChatInf.Character): number {
|
|
const g = Matcher.strToGender(c.gender);
|
|
|
|
if (g === null) {
|
|
return 0;
|
|
}
|
|
|
|
const myGender = Matcher.getTagValueList(TagId.Gender, me.character);
|
|
const myOrientation = Matcher.getTagValueList(TagId.Orientation, me.character);
|
|
const score = Matcher.scoreOrientationByGender(myGender, myOrientation, g);
|
|
|
|
return score.score;
|
|
}
|
|
|
|
|
|
getInterestScoreForStatus(c: CharacterFChatInf.Character): number {
|
|
if ((c.status === 'offline') || (c.status === 'away') || (c.status === 'busy') || (c.status === 'dnd'))
|
|
return -0.5;
|
|
|
|
if (c.status === 'looking')
|
|
return 0.5;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
getLastAdvertisementStatus(c: CharacterFChatInf.Character): number {
|
|
const ads = this.adCache.get(c.name);
|
|
|
|
if (!ads)
|
|
return 0;
|
|
|
|
const lastPost = ads.getDateLastPosted();
|
|
|
|
if (lastPost === null)
|
|
return 0;
|
|
|
|
const delta = Date.now() - lastPost.getTime();
|
|
|
|
if (delta < CharacterProfiler.ADVERTISEMENT_RECENT_RANGE)
|
|
return 1;
|
|
|
|
if (delta < CharacterProfiler.ADVERTISEMENT_POTENTIAL_RAGE)
|
|
return 0.5;
|
|
|
|
return -0.5; // has been advertising, but not recently, so likely busy
|
|
}
|
|
}
|