yukinovel
Version:
Yukinovel is a simple web visual novel engine.
102 lines (101 loc) • 3.51 kB
JavaScript
import { PluginBase } from "../utils/createPlugin";
/**
* Analytics Plugin
* Theo dõi hành vi người chơi và gửi analytics data
*/
export class AnalyticsPlugin extends PluginBase {
constructor() {
super();
this.metadata = {
name: 'analytics',
version: '1.0.0',
author: 'Yukiookii',
description: 'Plugin để theo dõi analytics và metrics của game',
priority: 10
};
this.api = {
getAnalytics: () => {
return this.analytics;
},
getPlaytime: () => {
if (!this.analytics)
return 0;
return Math.floor((new Date().getTime() - this.analytics.sessionStart.getTime()) / 1000);
},
exportData: () => {
return JSON.stringify(this.analytics, null, 2);
}
};
this.hooks = {
onStart: async (_context) => {
console.log('🎮 Game started!');
},
onSceneStarted: async (context) => {
const sceneId = context.scene?.id;
if (sceneId && this.analytics) {
console.log(`📺 Scene started: ${sceneId}`);
if (!this.analytics.sceneViews[sceneId]) {
this.analytics.sceneViews[sceneId] = 0;
}
this.analytics.sceneViews[sceneId]++;
}
},
onChoiceSelected: async (context) => {
const choice = context.choice;
if (choice && this.analytics) {
console.log(`🎯 Choice selected: ${choice.text}`);
this.analytics.choicesMade.push({
text: typeof choice.text === 'string' ? choice.text : choice.text?.en || 'Unknown',
action: choice.action,
target: choice.target,
timestamp: new Date(),
sceneId: context.state.currentScene
});
}
},
onSaved: async (context) => {
console.log(`💾 Game saved to slot ${context.slot}`);
},
onLoaded: async (context) => {
console.log(`📂 Game loaded from slot ${context.slot}`);
},
onEnd: async (_context) => {
console.log('🏁 Game ended!');
console.log('📊 Session Analytics:', this.analytics);
this.saveAnalytics();
}
};
this.analytics = {
sessionStart: new Date(),
sceneViews: {},
choicesMade: [],
playtime: 0,
};
}
async initialize(_game, _pluginManager) {
console.log('Analytics Plugin initialized');
this.analytics = {
sessionStart: new Date(),
sceneViews: {},
choicesMade: [],
playtime: 0
};
this.startTimeTracking();
}
startTimeTracking() {
this.timeInterval = setInterval(() => {
if (this.analytics) {
this.analytics.playtime++;
}
}, 1000);
}
saveAnalytics() {
if (this.timeInterval) {
clearInterval(this.timeInterval);
}
}
async dispose() {
console.log('Analytics Plugin disposed');
this.saveAnalytics();
}
}