minor tweaks

This commit is contained in:
Mr. Stallion 2024-07-05 20:38:57 -07:00
parent ad0aa7dee9
commit e11f833810
14 changed files with 217 additions and 34 deletions

View File

@ -1,22 +1,19 @@
# Changelog
## Canary
## Next?
* Merge Ad Editor and Post Ads?
* Fix Yiffbot portrait updates
* Remove broadcasts from logs; maybe into a dialog? where do we store them tho? At least shouldn't orange-highlight all convos
* Notify when bookmark/friend says something on a channel?
* Clicking a log entry opens the conversation at that point
## 1.27.0
* 'Non-binary' kink is now respected in gender matching (credit: [@FatCatClient](https://github.com/FatCatClient))
* OpenMoji is now treated as a fallback font (credit: [@FatCatClient](https://github.com/FatCatClient))
* Added two new UI themes: 'Dracula', and 'Dark Dimmed' (credit: [@FatCatClient](https://github.com/FatCatClient))
* Add high-quality portraits to Profile Helper
* FBot should always be a UNICORN match
* FBot should have extra buttons to help one-handed
* FBot should show up in Search Results... if online
* Remove broadcasts from logs; maybe into a dialog? where do we store them tho? At least shouldn't orange-highlight all convos
* Update e-icons
* Merge Ad Editor and Post Ads?
* Notify when bookmark/friend says something on a channel?
* Fix image previews (redgifs?)
* Fix Yiffbot portrait updates
* Address scoring issues per FCR Notes
* Clicking a log entry opens the conversation at that point
* Added two UI themes: 'Dracula', and 'Dark Dimmed' (credit: [@FatCatClient](https://github.com/FatCatClient))
* Each character can now set its own UI theme (credit: [@Nensec](https://github.com/Nensec))
* Bugfix: Characters with 'None' gender are no longer considered a mismatch against other genders
* Fixed Redgifs previews (again)
## 1.26.2
* Fixed a few cases where high-quality portraits were not displayed

View File

@ -11,6 +11,7 @@ This project contains contributions from:
* [WhiteHusky](https://github.com/WhiteHusky)
* [Abeehiltz](https://github.com/Abeehiltz)
* [greyhoof](https://github.com/greyhoof)
* [Nensec](https://github.com/Nensec)
* [F-List Team](https://github.com/f-list) (original F-Chat 3.0 client)

View File

@ -141,7 +141,7 @@ export default class EIconSelector extends CustomDialog {
case 'expressions':
return ['coolemoji', 'coughing emoji', 'flushedemoji', 'eyerollemoji', 'cryinglaughing', 'grinning emoji', 'party emoji',
'pensiveemoji', 'lipbite emoji', 'nauseous emoji', 'angryemoji', 'love2', 'clapemoji', 'heart eyes', 'kissing heart',
'flusteredcowboy', 'cowemoji', 'eggplantemoji', 'peachemoji', 'melting emoji', 'poopy', 'thinkingemoji', 'triumphemoji',
'cowemoji', 'eggplantemoji', 'peachemoji', 'melting emoji', 'poopy', 'thinkingemoji', 'triumphemoji',
'uwuemoji', 'voremoji', 'skullemoji', 'smugemoji', 'heartflooshed', 'blushpanic', 'fluttersorry', 'snake emoji', 'horseeyes', 'thehorse',
'catblob', 'catblobangery', 'splashemoji', 'tonguemoji', 'blobhugs', 'lickscreen', 'eyes emoji', 'nerdmeme', 'horsepls',
'e62pog', 'thirstytwi', 'bangfingerbang', 'chefs kiss', 'excuse me', 'psychopath', 'ashemote3', 'whentheohitsright',
@ -158,7 +158,7 @@ export default class EIconSelector extends CustomDialog {
'suitclubs', 'suitdiamonds', 'suithearts', 'suitspades', 'chainscuffs',
'num-1', 'num-2', 'num-3', 'num-4', 'num-5', 'num-6', 'seven', 'eight', '9ball',
'discordeye', 'streamlive', 'check mark', 'x mark', 'question mark', 'lubimark', 'questget',
'music', 'cam', 'phone', 'speaker emoji', 'laptop',
'music', 'cam', 'speaker emoji', 'laptop',
'naughtyfood', 'open2', 'dont look away', 'milkcartonreal', ];
case 'bubbles':
@ -168,26 +168,26 @@ export default class EIconSelector extends CustomDialog {
'buttslutbb', 'notgayoranything', 'onlyfans', 'horsecockneed', 'crimes', 'breed143', 'nagagross', 'willrim', 'muskslut',
'4lewdbubble', 'shimathatlewd', 'hypnosiss', 'imahypnoslut', 'sheepsass2', 'imahugeslut', 'notahealslut', 'ratedmilf',
'ratedstud', 'ratedslut', '5lewdbubble', 'xarcuminme', 'xarcumonme', 'choke me', 'iamgoingtopunchyou', 'snapmychoker',
'rude1', 'fuckbun', 'iamindanger', 'elves', 'sluttery', 'helpicantstopsuckingcocks', 'talkpooltoy', 'thatskindahot', 'ygod',
'simpbait', 'eyesuphere', 'fuckpiggy', 'peggable2', 'sydeanothere', 'nothingcan', 'pawslut', 'stupidboys', 'corpsestare-',
'rude1', 'fuckbun', 'iamindanger', 'elves', 'helpicantstopsuckingcocks', 'talkpooltoy', 'thatskindahot', 'ygod',
'simpbait', 'eyesuphere', 'fuckpiggy', 'peggable2', 'sydeanothere', 'nothingcan', 'pawslut', 'corpsestare-',
'dinnersex', 'plappening', 'fallout-standby', 'inbagg', 'request denied', 'goodboy0', 'goodending', 'milky2', 'howbadcanibe',
'gwanna', 'spitinmouth', 'bathwater'];
case 'sexual':
return ['kissspink', 'paytonkiss', 'coralbutt4', 'capstrip', 'pinkundress', 'collaredpet', 'jhab1', 'caninelover', 'pole',
'rorobutt2', 'fingerlick', 'lapgrind', 'jackthighs', 'a condom', 'wolf abs', 'musclefuck2', 'verobutt3', 'bumsqueeze',
'realahegao4', 'influencerhater', 'assfucker', 'gagged2', 'ballsack3', 'fingerblast3', 'sloppy01', 'sybian',
'rorobutt2', 'fingerlick', 'lapgrind', 'jackthighs', 'a condom', 'wolf abs', 'musclefuck2', 'verobutt3',
'realahegao4', 'influencerhater', 'gagged2', 'ballsack3', 'fingerblast3', 'sloppy01', 'sybian',
'floppyhorsecock', 'blackshem1', 'fingersucc', 'vullylick', 'fingersucc', 'cmontakeit', 'jessi flash', 'poju-butt',
'cheegrope2', 'patr1', 'ahega01 2', 'handjob1nuke', 'harmanfingers', '2buttw1', 'dropsqueeze',
'lixlove', 'bbctitjob6', 'appreciativetease', 'bimbowhisper', 'subj3', 'salivashare', 'ballsworship3', 'wolfsknot2', 'gaykiss',
'slurpkiss', 'absbulge', 'cockiss', 'horsedick11', 'knotknotknot', 'g4ebulge', 'blackadamrough', 'knotdog', 'flaunt', 'cummiefj', 'lovetosuck',
'worship', 'hopelessly in love', 'knotts', 'cockloveeee', 'donglove', 'knotjob2', 'cummz', 'every drop', 'edgyoops',
'worship', 'hopelessly in love', 'cockloveeee', 'donglove', 'knotjob2', 'cummz', 'every drop', 'edgyoops',
'orccummies2', 'oralcreampie100px', 'horseoral9a', 'swallowit', 'realahegao4', 'gayicon2', 'slut4', 'hossspurties2', 'cumringgag',
'jillbimbogiffell2'];
case 'memes':
return ['guncock', 'michaelguns', 'watchbadass', 'gonnabang', 'flirting101', 'monkeymeme', 'monkeymeme2', 'loudnoises',
'nyancat', 'gayb', 'fortasshole', 'dickletsign', 'sausageface', 'siren0', 'apologize to god', 'jabbalick', 'zeldawink',
return ['guncock', 'michaelguns', 'watchbadass', 'gonnabang', 'flirting101', 'loudnoises',
'nyancat', 'gayb', 'fortasshole', 'dickletsign', 'hotdogface', 'siren0', 'apologize to god', 'jabbalick', 'zeldawink',
'whatislove', 'surprisemothafucka', 'females', 'thanksihateit', 'hell is this', 'confused travolta', 'no words', 'coffindance',
'homelander', 'thatsapenis', 'pennyhee', 'kermitbusiness', 'goodbye', 'rickle', 'shiamagic', 'oag', ];

View File

@ -73,12 +73,13 @@
import CharacterSearchHistory from './CharacterSearchHistory.vue';
import { Matcher } from '../learn/matcher';
import {
Gender,
kinkMatchScoreMap,
kinkMatchWeights,
nonAnthroSpecies,
nonAnthroSpecies, Orientation,
Species,
speciesMapping,
speciesNames
speciesNames, TagId
} from '../learn/matcher-types';
import { CharacterCacheRecord } from '../learn/profile-cache';
import Bluebird from 'bluebird';
@ -273,6 +274,34 @@
console.log('Done!');
}
getYiffBotCompatibleGender(): Character.Gender {
const g = Matcher.getTagValueList(TagId.Gender, core.characters.ownProfile.character);
const o = Matcher.getTagValueList(TagId.Orientation, core.characters.ownProfile.character);
if (o === Orientation.Straight || o === Orientation.Unsure || _.isNil(o)) {
if (g === Gender.Male) {
return 'Female';
}
if (g === Gender.Female) {
return 'Male';
}
}
if (o === Orientation.Gay && g) {
return g === Gender.Male ? 'Male' : 'Female';
}
if (o === Orientation.BiFemalePreference) {
return 'Female';
}
if (o === Orientation.BiMalePreference) {
return 'Male';
}
return _.sample(['Male', 'Female']) as Character.Gender;
}
@Hook('mounted')
mounted(): void {
@ -311,6 +340,16 @@
this.hasReceivedResults = true;
this.results = results;
if (this.isYiffBot4000Online()) {
const char = core.characters.get('YiffBot 4000');
(char as any).status = 'looking';
(char as any).gender = this.getYiffBotCompatibleGender();
(char as any).statusText = 'Try AI play with any gender, orientation & kink!';
this.results.push({ character: char, profile: core.cache.profileCache.getSync('YiffBot 4000') });
}
this.resort(results);
});
@ -548,15 +587,19 @@
this.shouldShowAvatar = core.state.settings.risingShowPortraitInMessage;
this.results = [];
this.state = 'results';
this.error = '';
const data: Connection.ClientCommands['FKS'] & {[key: string]: (string | number)[]} = {kinks: []};
for(const key in this.data) {
const item = this.data[<keyof SearchData>key]; // SearchData is correct
if(item.length > 0 && key !== 'bodytypes')
data[key] = key === 'kinks' ? (<SearchKink[]>item).map((x) => x.id) : (<string[]>item);
}
core.connection.send('FKS', data);
// tslint:disable-next-line

View File

@ -108,6 +108,12 @@
<a class="btn btn-sm btn-light" style="position:absolute;right:5px;top:50%;transform:translateY(-50%);line-height:0;z-index:10"
@click="hideSearch"><i class="fas fa-times"></i></a>
</div>
<div class="yiffbot-controls" v-if="isYiffBot()">
<div class="btn-group">
<div class="btn btn-sm btn-outline-secondary" @click="onYiffBotContinuePost">#continue</div>
<div class="btn btn-sm btn-outline-secondary" @click="onYiffBotRetryPost">#retry</div>
</div>
</div>
<div class="auto-ads" v-show="isAutopostingAds()">
<h4>{{l('admgr.activeHeader')}}</h4>
<div class="update">{{adAutoPostUpdate}}</div>
@ -201,7 +207,7 @@
import CharacterAdView from './character/CharacterAdView.vue';
import {Editor} from './bbcode';
import CommandHelp from './CommandHelp.vue';
import { characterImage, errorToString, getByteLength, getKey } from './common';
import { characterImage, errorToString, getByteLength, getKey, Message } from './common';
import ConversationSettings from './ConversationSettings.vue';
import ConversationAdSettings from './ads/ConversationAdSettings.vue';
import core from './core';
@ -698,6 +704,36 @@
const member = conv.channel.members[core.connection.character];
return member !== undefined && member.rank > Channel.Rank.Member;
}
isYiffBot(): boolean {
if (!this.isPrivate(this.conversation)) {
return false;
}
return this.conversation.character.name === 'YiffBot 4000';
}
async onYiffBotContinuePost(): Promise<void> {
if (!this.isPrivate(this.conversation)) {
return;
}
const conv = (<Conversation.PrivateConversation>this.conversation);
await conv.sendMessageEx('#continue');
await this.messageAdded(this.conversation.messages as Message[]);
}
async onYiffBotRetryPost(): Promise<void> {
if (!this.isPrivate(this.conversation)) {
return;
}
const conv = (<Conversation.PrivateConversation>this.conversation);
await conv.sendMessageEx('#retry');
await this.messageAdded(this.conversation.messages as Message[]);
}
}
</script>
@ -1052,4 +1088,12 @@
min-width: 1.2em;
max-width: 1.2em;
}
.yiffbot-controls {
.btn-group {
margin-left: 70px;
margin-top: 10px;
margin-bottom: 10px;
}
}
</style>

View File

@ -249,6 +249,32 @@ class PrivateConversation extends Conversation implements Interfaces.PrivateConv
return state.savePinned();
}
public async sendMessageEx(messageText: string): Promise<void> {
if(this.character.status === 'offline') {
this.errorText = l('chat.errorOffline', this.character.name);
return;
}
if(this.character.isIgnored) {
this.errorText = l('chat.errorIgnored', this.character.name);
return;
}
await Conversation.conversationThroat(
async() => {
await Conversation.testPostDelay();
core.connection.send('PRI', {recipient: this.name, message: messageText});
core.cache.markLastPostTime();
const message = createMessage(MessageType.Message, core.characters.ownCharacter, messageText);
this.safeAddMessage(message);
if(core.state.settings.logMessages) await core.logs.logMessage(this, message);
}
);
}
protected async doSend(): Promise<void> {
await this.logPromise;
if(this.character.status === 'offline') {

View File

@ -67,6 +67,8 @@ export namespace Conversation {
export interface PrivateConversation extends TabConversation {
readonly character: Character
readonly typingStatus: TypingStatus
sendMessageEx(text: string): Promise<void>;
}
export interface ChannelConversation extends TabConversation {

View File

@ -167,7 +167,7 @@ export class ImageDomMutator {
this.add('sexbot.gallery', this.getBaseJsMutatorScript(['video.hero', 'video']));
this.add('imagefap.com', this.getBaseJsMutatorScript(['.image-wrapper img', 'video', 'img']));
this.add('myhentaicomics.com', this.getBaseJsMutatorScript(['#entire_image img', 'video', 'img']));
this.add('redgifs.com', this.getBaseJsMutatorScript(['video'], true, [], false, true));
this.add('redgifs.com', this.getBaseJsMutatorScript(['video'])); // , true, [], false, true));
this.add('furaffinity.net', this.getBaseJsMutatorScript(['#submissionImg', 'video', 'img']));
this.add('rule34.paheal.net', this.getBaseJsMutatorScript(['#main_image', 'video', 'img']));
this.add('xhamster.com', this.getBaseJsMutatorScript(['#photo_slider video', '#photo_slider img', 'video', 'img']));

View File

@ -51,7 +51,7 @@ changelog: https://github.com/hearmeneigh/fchat-rising/blob/master/CHANGELOG.md
installurl: https://github.com/hearmeneigh/fchat-rising/wiki
download:
version: 1.26.2
version: 1.27.0
url: https://github.com/hearmeneigh/fchat-rising/releases/latest/download/F-Chat-Rising-%PLATFORM_TAIL%

View File

@ -1,6 +1,6 @@
{
"name": "fchat",
"version": "1.26.2",
"version": "1.27.0",
"author": "The F-List Team and Mister Stallion (Esq.)",
"description": "F-List.net Chat Client",
"main": "main.js",

View File

@ -238,6 +238,62 @@ export class Matcher {
return report;
}
static getYiffBot4000MatchReport(you: Character, them: Character): MatchReport {
const scores: MatchResultScores = {
[TagId.Orientation]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.Gender]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.Age]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.FurryPreference]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.Species]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.SubDomRole]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.Kinks]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.PostLength]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.Position]: new Score(Scoring.MATCH, 'Perfect match!'),
[TagId.BodyType]: new Score(Scoring.MATCH, 'Perfect match!')
};
const yourAnalysis = new CharacterAnalysis(you);
const theirAnalysis = new CharacterAnalysis(them);
return {
_isVue: true,
you: {
you,
them,
scores,
info: {
species: Matcher.species(you),
gender: Matcher.getTagValueList(TagId.Gender, you),
orientation: Matcher.getTagValueList(TagId.Orientation, you)
},
total: _.sum(_.values(scores).map((s: Score) => s.score)),
yourAnalysis,
theirAnalysis
},
them: {
you: them,
them: you,
scores,
info: {
species: Matcher.species(them),
gender: Matcher.getTagValueList(TagId.Gender, them),
orientation: Matcher.getTagValueList(TagId.Orientation, them)
} ,
total: _.sum(_.values(scores).map((s: Score) => s.score)),
yourAnalysis: theirAnalysis,
theirAnalysis: yourAnalysis
},
youMultiSpecies: false,
themMultiSpecies: false,
merged: scores,
score: Scoring.MATCH,
details: {
totalScoreDimensions: _.values(scores).length * 2,
dimensionsAtScoreLevel: _.values(scores).length * 2
}
};
}
static identifyBestMatchReport(you: Character, them: Character): MatchReport {
const reportStartTime = Date.now();
@ -248,6 +304,10 @@ export class Matcher {
let bestScoreLevelCount = -10000;
let bestReport: MatchReport;
if (you.name === 'YiffBot 4000' || them.name === 'YiffBot 4000') {
return Matcher.getYiffBot4000MatchReport(you, them);
}
for(const yourAnalysis of yourCharacterAnalyses) {
for (const theirAnalysis of theirCharacterAnalyses) {
const youThem = new Matcher(yourAnalysis.character, theirAnalysis.character, yourAnalysis.analysis, theirAnalysis.analysis);
@ -437,7 +497,7 @@ export class Matcher {
static scoreOrientationByGender(yourGender: Gender | null, yourOrientation: Orientation | null, theirGender: Gender | null): Score {
if ((yourGender === null) || (theirGender === null) || (yourOrientation === null))
if ((yourGender === null) || (theirGender === null) || (yourOrientation === null) || yourGender === Gender.None || theirGender === Gender.None)
return new Score(Scoring.NEUTRAL);
// CIS
@ -727,8 +787,9 @@ export class Matcher {
const yourOrientation = this.yourAnalysis.orientation;
const theirGender = this.theirAnalysis.gender;
if (theirGender === null)
if (theirGender === null) {
return new Score(Scoring.NEUTRAL);
}
const genderName = `${Gender[theirGender].toLowerCase()}s`;
const genderKinkScore = Matcher.getKinkGenderPreference(you, theirGender);
@ -1375,6 +1436,10 @@ export class Matcher {
match: MatchReport,
penalty: number
): number {
if (match.you.you.name === 'YiffBot 4000' || match.you.them.name === 'YiffBot 4000') {
return kinkMatchWeights.unicornThreshold;
}
const totalScoreDimensions = match ? Matcher.countScoresTotal(match) : 0;
const dimensionsAtScoreLevel = match ? (Matcher.countScoresAtLevel(match, score) || 0) : 0;
const dimensionsAboveScoreLevel = match ? (Matcher.countScoresAboveLevel(match, Math.max(score, Scoring.WEAK_MATCH))) : 0;

View File

@ -1,6 +1,6 @@
{
"name": "f-list-rising",
"version": "1.26.2",
"version": "1.27.0",
"author": "The F-List Team and and Mister Stallion (Esq.)",
"description": "A heavily modded F-Chat 3.0 client for F-List",
"license": "MIT",

View File

@ -203,6 +203,10 @@
shouldShowMatch(): boolean {
if (this.character?.character.name === 'YiffBot 4000') {
return false;
}
return core.state.settings.risingAdScore;
}

View File

@ -11,7 +11,8 @@
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
"esModuleInterop": true,
"experimentalDecorators": true
},
"include": ["./electron/main.ts"]
}