AeThex-OS/temp-connect-extract/AeThex-Connect-main/nexus-sdk/AeThexConnectPlugin.js
MrPiglr b3c308b2c8 Add functional marketplace modules, bottom nav bar, root terminal, arcade games
- ModuleManager: Central tracking for installed marketplace modules
- DataAnalyzerWidget: Real-time CPU/RAM/Battery/Storage widget (unlocked by Data Analyzer module)
- BottomNavBar: Navigation bar for Projects/Chat/Marketplace/Settings
- RootShell: Real root command execution utility
- TerminalActivity: Full root shell with neofetch, sysinfo, real Linux commands
- Terminal Pro module: Adds aliases (ll, la, h), command history
- ArcadeActivity + SnakeGame: Pixel Arcade module unlocks retro games
- fade_in/fade_out animations for smooth transitions
2026-02-18 22:03:50 -07:00

442 lines
11 KiB
JavaScript

/**
* AeThex Connect Plugin for Nexus Engine
* Integrates AeThex Connect communication into games
*
* @version 1.0.0
* @license MIT
*/
class AeThexConnectPlugin {
constructor(nexusEngine, config = {}) {
this.nexus = nexusEngine;
this.config = {
apiUrl: config.apiUrl || 'https://connect.aethex.app/api',
apiKey: config.apiKey,
enableOverlay: config.enableOverlay !== false,
enableNotifications: config.enableNotifications !== false,
overlayPosition: config.overlayPosition || 'top-right',
autoMute: config.autoMute !== false,
...config
};
this.sessionId = null;
this.overlayConfig = null;
this.overlayElement = null;
this.isInitialized = false;
}
/**
* Initialize plugin
*/
async initialize() {
try {
console.log('[AeThex Connect] Initializing...');
// Get player info from Nexus
const player = await this.nexus.getPlayer();
if (!player || !player.id) {
throw new Error('Failed to get player information from Nexus');
}
// Start game session with AeThex Connect
const response = await fetch(`${this.config.apiUrl}/nexus/sessions/start`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Nexus-API-Key': this.config.apiKey,
'X-Nexus-Player-ID': player.id
},
body: JSON.stringify({
nexusPlayerId: player.id,
gameId: this.nexus.gameId,
gameName: this.nexus.gameName,
metadata: {
platform: this.nexus.platform || 'unknown',
playerName: player.displayName || player.username
}
})
});
const data = await response.json();
if (data.success) {
this.sessionId = data.session.id;
this.overlayConfig = data.overlayConfig;
this.isInitialized = true;
// Initialize overlay if enabled
if (this.overlayConfig.enabled && this.config.enableOverlay) {
this.initializeOverlay();
}
// Setup event listeners
this.setupEventListeners();
console.log('[AeThex Connect] Initialized successfully');
console.log('[AeThex Connect] Session ID:', this.sessionId);
return true;
} else {
throw new Error(data.error || 'Failed to start session');
}
} catch (error) {
console.error('[AeThex Connect] Initialization failed:', error);
return false;
}
}
/**
* Setup event listeners for game state changes
*/
setupEventListeners() {
// When player enters match
this.nexus.on('match:start', async (matchData) => {
console.log('[AeThex Connect] Match started');
await this.updateSessionState('in-match', {
mapName: matchData.map,
gameMode: matchData.mode,
teamId: matchData.teamId
});
// Auto-mute if configured
if (this.overlayConfig.autoMute) {
this.triggerAutoMute();
}
});
// When player returns to menu
this.nexus.on('match:end', async (matchData) => {
console.log('[AeThex Connect] Match ended');
await this.updateSessionState('in-menu', {
score: matchData.score,
won: matchData.won,
duration: matchData.duration
});
// Unmute
if (this.overlayConfig.autoMute) {
this.triggerAutoUnmute();
}
});
// When game closes
this.nexus.on('game:exit', async () => {
console.log('[AeThex Connect] Game exiting');
await this.endSession();
});
// When player pauses
this.nexus.on('game:pause', async () => {
await this.updateSessionState('paused');
});
// When player resumes
this.nexus.on('game:resume', async () => {
await this.updateSessionState('active');
});
}
/**
* Update session state
*/
async updateSessionState(state, metadata = {}) {
if (!this.sessionId || !this.isInitialized) return;
try {
await fetch(`${this.config.apiUrl}/nexus/sessions/${this.sessionId}/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Nexus-API-Key': this.config.apiKey
},
body: JSON.stringify({ state, metadata })
});
} catch (error) {
console.error('[AeThex Connect] Failed to update session:', error);
}
}
/**
* End session
*/
async endSession() {
if (!this.sessionId || !this.isInitialized) return;
try {
await fetch(`${this.config.apiUrl}/nexus/sessions/${this.sessionId}/end`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Nexus-API-Key': this.config.apiKey
},
body: JSON.stringify({
duration: this.getSessionDuration(),
metadata: {}
})
});
this.sessionId = null;
this.isInitialized = false;
// Remove overlay
if (this.overlayElement) {
this.overlayElement.remove();
this.overlayElement = null;
}
} catch (error) {
console.error('[AeThex Connect] Failed to end session:', error);
}
}
/**
* Initialize in-game overlay
*/
initializeOverlay() {
// Create iframe overlay
const overlay = document.createElement('iframe');
overlay.id = 'aethex-connect-overlay';
overlay.src = `${this.config.apiUrl.replace('/api', '')}/overlay?session=${this.sessionId}`;
// Position based on config
const positions = {
'top-right': 'top: 20px; right: 20px;',
'top-left': 'top: 20px; left: 20px;',
'bottom-right': 'bottom: 20px; right: 20px;',
'bottom-left': 'bottom: 20px; left: 20px;'
};
overlay.style.cssText = `
position: fixed;
${positions[this.config.overlayPosition] || positions['top-right']}
width: 320px;
height: 480px;
border: none;
z-index: 999999;
opacity: ${this.overlayConfig.opacity || 0.9};
pointer-events: auto;
transition: all 0.3s ease;
`;
// Add to DOM
document.body.appendChild(overlay);
this.overlayElement = overlay;
// Listen for overlay messages
window.addEventListener('message', (event) => {
// Security check
const allowedOrigins = [
'https://connect.aethex.app',
'http://localhost:3000',
'http://localhost:5173'
];
if (!allowedOrigins.includes(event.origin)) return;
this.handleOverlayMessage(event.data);
});
console.log('[AeThex Connect] Overlay initialized');
}
/**
* Handle overlay messages
*/
handleOverlayMessage(message) {
switch (message.type) {
case 'minimize':
this.minimizeOverlay(message.minimized);
break;
case 'notification':
this.showNotification(message.data);
break;
case 'friend_invite':
this.handleFriendInvite(message.data);
break;
}
}
/**
* Minimize/restore overlay
*/
minimizeOverlay(minimized) {
if (!this.overlayElement) return;
if (minimized) {
this.overlayElement.style.width = '60px';
this.overlayElement.style.height = '60px';
} else {
this.overlayElement.style.width = '320px';
this.overlayElement.style.height = '480px';
}
}
/**
* Show in-game notification
*/
showNotification(notification) {
if (!this.config.enableNotifications) return;
// Create notification element
const notif = document.createElement('div');
notif.className = 'aethex-notification';
notif.innerHTML = `
<div class="notif-icon">${notification.icon || '💬'}</div>
<div class="notif-content">
<div class="notif-title">${this.escapeHtml(notification.title)}</div>
<div class="notif-body">${this.escapeHtml(notification.body)}</div>
</div>
`;
// Add styles if not already added
this.injectNotificationStyles();
document.body.appendChild(notif);
// Auto-remove after 5 seconds
setTimeout(() => {
notif.style.opacity = '0';
setTimeout(() => notif.remove(), 300);
}, 5000);
console.log('[AeThex Connect] Notification shown:', notification.title);
}
/**
* Inject notification styles
*/
injectNotificationStyles() {
if (document.getElementById('aethex-notif-styles')) return;
const style = document.createElement('style');
style.id = 'aethex-notif-styles';
style.textContent = `
.aethex-notification {
position: fixed;
top: 20px;
right: 20px;
width: 320px;
background: rgba(20, 20, 30, 0.95);
backdrop-filter: blur(10px);
border-radius: 8px;
padding: 16px;
display: flex;
gap: 12px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
animation: slideIn 0.3s ease-out;
z-index: 1000000;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
transition: opacity 0.3s;
}
@keyframes slideIn {
from {
transform: translateX(400px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.aethex-notification .notif-icon {
font-size: 24px;
flex-shrink: 0;
}
.aethex-notification .notif-content {
flex: 1;
}
.aethex-notification .notif-title {
font-size: 14px;
font-weight: 600;
color: #fff;
margin-bottom: 4px;
}
.aethex-notification .notif-body {
font-size: 13px;
color: #aaa;
}
`;
document.head.appendChild(style);
}
/**
* Trigger auto-mute for voice chat
*/
triggerAutoMute() {
if (!this.overlayElement) return;
this.overlayElement.contentWindow.postMessage({
type: 'auto_mute',
mute: true
}, '*');
console.log('[AeThex Connect] Auto-mute triggered');
}
/**
* Trigger auto-unmute
*/
triggerAutoUnmute() {
if (!this.overlayElement) return;
this.overlayElement.contentWindow.postMessage({
type: 'auto_mute',
mute: false
}, '*');
console.log('[AeThex Connect] Auto-unmute triggered');
}
/**
* Handle friend invite
*/
handleFriendInvite(data) {
console.log('[AeThex Connect] Friend invite received:', data);
// Game-specific handling of friend invites
// Could show custom UI or trigger game's friend system
}
/**
* Get session duration in seconds
*/
getSessionDuration() {
// This would be calculated based on session start time
// For now, return 0 as placeholder
return 0;
}
/**
* Escape HTML to prevent XSS
*/
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
/**
* Cleanup and destroy plugin
*/
destroy() {
this.endSession();
if (this.overlayElement) {
this.overlayElement.remove();
}
console.log('[AeThex Connect] Plugin destroyed');
}
}
// Export for different module systems
if (typeof module !== 'undefined' && module.exports) {
module.exports = AeThexConnectPlugin;
}
if (typeof window !== 'undefined') {
window.AeThexConnectPlugin = AeThexConnectPlugin;
}