Compare commits
2 Commits
1dc96a53ee
...
b7bf1cf9ea
| Author | SHA1 | Date | |
|---|---|---|---|
| b7bf1cf9ea | |||
| 9aba81960a |
@@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Grepolis Remote Control
|
// @name Grepolis Remote Control
|
||||||
// @namespace http://tampermonkey.net/
|
// @namespace http://tampermonkey.net/
|
||||||
// @version 3.6.7
|
// @version 3.5.8
|
||||||
// @description Polls grepo.haunter-pets.top for remote commands and executes them in-game (Multi-Player)
|
// @description Polls grepo.haunter-pets.top for remote commands and executes them in-game (Multi-Player)
|
||||||
// @author Dimitrios
|
// @author Dimitrios
|
||||||
// @match https://*.grepolis.com/game/*
|
// @match https://*.grepolis.com/game/*
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
if (farm.attributes.island_x !== ix || farm.attributes.island_y !== iy) return;
|
if (farm.attributes.island_x !== ix || farm.attributes.island_y !== iy) return;
|
||||||
relCollection.models.forEach(rel => {
|
relCollection.models.forEach(rel => {
|
||||||
if (rel.attributes.farm_town_id === farm.attributes.id &&
|
if (rel.attributes.farm_town_id === farm.attributes.id &&
|
||||||
rel.attributes.relation_status >= 0) {
|
rel.attributes.relation_status >= 1) {
|
||||||
farms.push({
|
farms.push({
|
||||||
farm_town_id: farm.attributes.id,
|
farm_town_id: farm.attributes.id,
|
||||||
farm_name: farm.attributes.name || '',
|
farm_name: farm.attributes.name || '',
|
||||||
@@ -814,120 +814,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto Bandit Camp: if enabled, attack/claim when ready
|
|
||||||
if (farmSettings.bandit_camp_enabled) {
|
|
||||||
try {
|
|
||||||
// player_id already declared above in pollAndExecute scope
|
|
||||||
const currentTownId = uw.ITowns?.getCurrentTown?.()?.id
|
|
||||||
|| Object.keys(uw.ITowns?.towns || {})[0]
|
|
||||||
|| null;
|
|
||||||
if (!player_id || !currentTownId) {
|
|
||||||
log(`⚔️ Bandit Camp: Missing globals — player_id=${player_id} town_id=${currentTownId}`);
|
|
||||||
} else {
|
|
||||||
// First try: MM collection (works once camp was opened in-game)
|
|
||||||
let spotData = uw.MM.getOnlyCollectionByName('PlayerAttackSpot')?.models?.[0]?.attributes || null;
|
|
||||||
|
|
||||||
// Second try: use gpAjax with a callback — it handles auth/hash internally
|
|
||||||
if (!spotData) {
|
|
||||||
spotData = await new Promise((resolve) => {
|
|
||||||
try {
|
|
||||||
uw.gpAjax.ajaxPost('frontend_bridge', 'execute', {
|
|
||||||
model_url: `PlayerAttackSpot/${player_id}`,
|
|
||||||
action_name: 'get_own',
|
|
||||||
captcha: null,
|
|
||||||
arguments: {},
|
|
||||||
town_id: currentTownId,
|
|
||||||
nl_init: true
|
|
||||||
}, false, {
|
|
||||||
success: function(data) {
|
|
||||||
// Response may contain the spot data directly
|
|
||||||
const d = data?.PlayerAttackSpot
|
|
||||||
|| data?.data?.PlayerAttackSpot?.[player_id]
|
|
||||||
|| data?.[player_id]
|
|
||||||
|| data;
|
|
||||||
resolve((d && d.cooldown_at !== undefined) ? d : null);
|
|
||||||
},
|
|
||||||
error: function() { resolve(null); }
|
|
||||||
});
|
|
||||||
} catch(e) { resolve(null); }
|
|
||||||
});
|
|
||||||
|
|
||||||
// After the gpAjax call, MM might now have the model
|
|
||||||
if (!spotData) {
|
|
||||||
spotData = uw.MM.getOnlyCollectionByName('PlayerAttackSpot')?.models?.[0]?.attributes || null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spotData) {
|
|
||||||
log('⚔️ Bandit Camp: Could not load spot data. Open the Bandit Camp window in-game once to let the game load it.');
|
|
||||||
} else {
|
|
||||||
const nowTs = Math.floor(Date.now() / 1000);
|
|
||||||
const spotId = spotData.id || player_id;
|
|
||||||
const townId = spotData.town_id || currentTownId;
|
|
||||||
|
|
||||||
log(`⚔️ Bandit Monitor -> Cooldown in: ${Math.max(0, spotData.cooldown_at - nowTs)}s | Reward: ${spotData.reward_available} | Level: ${spotData.level}`);
|
|
||||||
|
|
||||||
if (spotData.reward_available) {
|
|
||||||
log('⚔️ Bandit Camp: Reward available! Waiting before claiming...');
|
|
||||||
await sleep(randInt(8000, 24000));
|
|
||||||
uw.gpAjax.ajaxPost('frontend_bridge', 'execute', {
|
|
||||||
model_url: `PlayerAttackSpot/${spotId}`,
|
|
||||||
action_name: 'useReward',
|
|
||||||
captcha: null,
|
|
||||||
arguments: {},
|
|
||||||
town_id: townId,
|
|
||||||
nl_init: true
|
|
||||||
});
|
|
||||||
log('⚔️ Bandit Camp: Reward claimed!');
|
|
||||||
} else if (spotData.cooldown_at <= nowTs) {
|
|
||||||
let hasMovements = false;
|
|
||||||
try {
|
|
||||||
const movements = uw.MM.getOnlyCollectionByName('MovementCommand')?.models || [];
|
|
||||||
hasMovements = movements.length > 0;
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
if (!hasMovements) {
|
|
||||||
const town = uw.ITowns?.getTown?.(townId) || uw.ITowns?.towns?.[townId];
|
|
||||||
if (town) {
|
|
||||||
const myUnits = town.units() || {};
|
|
||||||
const allowedUnits = ['sword', 'slinger', 'archer', 'hoplite', 'rider', 'chariot', 'catapult'];
|
|
||||||
const sendUnits = {};
|
|
||||||
let totalUnits = 0;
|
|
||||||
for (let u of allowedUnits) {
|
|
||||||
if ((myUnits[u] || 0) > 0) {
|
|
||||||
sendUnits[u] = myUnits[u];
|
|
||||||
totalUnits += myUnits[u];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (totalUnits > 0) {
|
|
||||||
log(`⚔️ Bandit Camp: Attacking with ${totalUnits} units...`);
|
|
||||||
await sleep(randInt(8000, 24000));
|
|
||||||
uw.gpAjax.ajaxPost('frontend_bridge', 'execute', {
|
|
||||||
model_url: `PlayerAttackSpot/${spotId}`,
|
|
||||||
action_name: 'attack',
|
|
||||||
captcha: null,
|
|
||||||
arguments: sendUnits,
|
|
||||||
town_id: townId,
|
|
||||||
nl_init: true
|
|
||||||
});
|
|
||||||
log('⚔️ Bandit Camp: Attack sent!');
|
|
||||||
} else {
|
|
||||||
log('⚔️ Bandit Camp: No units available.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log('⚔️ Bandit Camp: Troops still returning — waiting...');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
log(`⚔️ Bandit camp error: ${e.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (cmdData.sync_requested) {
|
if (cmdData.sync_requested) {
|
||||||
log('Sync requested by server — pushing state immediately');
|
log('Sync requested by server — pushing state immediately');
|
||||||
pushState();
|
pushState();
|
||||||
|
|||||||
@@ -104,11 +104,10 @@ def get_pending_command():
|
|||||||
|
|
||||||
# Also return current farm settings so TM knows loot_option
|
# Also return current farm settings so TM knows loot_option
|
||||||
farm_row = c.execute(
|
farm_row = c.execute(
|
||||||
'SELECT enabled, bandit_camp_enabled, loot_option FROM farm_settings WHERE player_id = ?', (player_id,)
|
'SELECT enabled, loot_option FROM farm_settings WHERE player_id = ?', (player_id,)
|
||||||
).fetchone()
|
).fetchone()
|
||||||
farm_settings = {
|
farm_settings = {
|
||||||
'enabled': bool(farm_row['enabled']) if farm_row else False,
|
'enabled': bool(farm_row['enabled']) if farm_row else False,
|
||||||
'bandit_camp_enabled': bool(farm_row['bandit_camp_enabled']) if farm_row else False,
|
|
||||||
'loot_option': farm_row['loot_option'] if farm_row else 1
|
'loot_option': farm_row['loot_option'] if farm_row else 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,12 +70,12 @@ def get_farm_settings():
|
|||||||
player_id = request.args.get('player_id')
|
player_id = request.args.get('player_id')
|
||||||
conn = get_db()
|
conn = get_db()
|
||||||
row = conn.execute(
|
row = conn.execute(
|
||||||
'SELECT enabled, bandit_camp_enabled, loot_option FROM farm_settings WHERE player_id = ?', (player_id,)
|
'SELECT enabled, loot_option FROM farm_settings WHERE player_id = ?', (player_id,)
|
||||||
).fetchone()
|
).fetchone()
|
||||||
conn.close()
|
conn.close()
|
||||||
if row:
|
if row:
|
||||||
return jsonify({'enabled': bool(row['enabled']), 'bandit_camp_enabled': bool(row['bandit_camp_enabled']), 'loot_option': row['loot_option']})
|
return jsonify({'enabled': bool(row['enabled']), 'loot_option': row['loot_option']})
|
||||||
return jsonify({'enabled': False, 'bandit_camp_enabled': False, 'loot_option': 1})
|
return jsonify({'enabled': False, 'loot_option': 1})
|
||||||
|
|
||||||
@dashboard.route('/dashboard/farm-settings', methods=['POST'])
|
@dashboard.route('/dashboard/farm-settings', methods=['POST'])
|
||||||
def set_farm_settings():
|
def set_farm_settings():
|
||||||
@@ -84,18 +84,16 @@ def set_farm_settings():
|
|||||||
return jsonify({'error': 'missing player_id'}), 400
|
return jsonify({'error': 'missing player_id'}), 400
|
||||||
player_id = data['player_id']
|
player_id = data['player_id']
|
||||||
enabled = 1 if data.get('enabled') else 0
|
enabled = 1 if data.get('enabled') else 0
|
||||||
bandit_camp_enabled = 1 if data.get('bandit_camp_enabled') else 0
|
|
||||||
loot_option = int(data.get('loot_option', 1))
|
loot_option = int(data.get('loot_option', 1))
|
||||||
conn = get_db()
|
conn = get_db()
|
||||||
conn.execute('''
|
conn.execute('''
|
||||||
INSERT INTO farm_settings (player_id, enabled, bandit_camp_enabled, loot_option, updated_at)
|
INSERT INTO farm_settings (player_id, enabled, loot_option, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
ON CONFLICT(player_id) DO UPDATE SET
|
ON CONFLICT(player_id) DO UPDATE SET
|
||||||
enabled = excluded.enabled,
|
enabled = excluded.enabled,
|
||||||
bandit_camp_enabled = excluded.bandit_camp_enabled,
|
|
||||||
loot_option = excluded.loot_option,
|
loot_option = excluded.loot_option,
|
||||||
updated_at = excluded.updated_at
|
updated_at = excluded.updated_at
|
||||||
''', (player_id, enabled, bandit_camp_enabled, loot_option, datetime.utcnow().isoformat()))
|
''', (player_id, enabled, loot_option, datetime.utcnow().isoformat()))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return jsonify({'ok': True})
|
return jsonify({'ok': True})
|
||||||
|
|||||||
@@ -255,15 +255,6 @@
|
|||||||
<span style="color:#888; font-size:0.85rem;" id="toggle-hint">Ανενεργό</span>
|
<span style="color:#888; font-size:0.85rem;" id="toggle-hint">Ανενεργό</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="toggle-row">
|
|
||||||
<span class="toggle-label">Στρατόπεδο Ληστών (Auto)</span>
|
|
||||||
<label class="toggle">
|
|
||||||
<input type="checkbox" id="bandit-camp-enabled">
|
|
||||||
<span class="slider"></span>
|
|
||||||
</label>
|
|
||||||
<span style="color:#888; font-size:0.85rem;" id="bandit-toggle-hint">Ανενεργό</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="margin-bottom: 0.75rem; font-size: 0.85rem; color: #888;">Επίπεδο Λεηλασίας:</div>
|
<div style="margin-bottom: 0.75rem; font-size: 0.85rem; color: #888;">Επίπεδο Λεηλασίας:</div>
|
||||||
<div class="option-grid">
|
<div class="option-grid">
|
||||||
<button class="option-btn selected" data-option="1">
|
<button class="option-btn selected" data-option="1">
|
||||||
@@ -346,36 +337,27 @@
|
|||||||
// -- Toggle hint text --
|
// -- Toggle hint text --
|
||||||
document.getElementById('farm-enabled').addEventListener('change', function () {
|
document.getElementById('farm-enabled').addEventListener('change', function () {
|
||||||
document.getElementById('toggle-hint').textContent = this.checked ? '🟢 Ενεργό' : 'Ανενεργό';
|
document.getElementById('toggle-hint').textContent = this.checked ? '🟢 Ενεργό' : 'Ανενεργό';
|
||||||
updateStatusBar(this.checked, document.getElementById('bandit-camp-enabled').checked);
|
updateStatusBar(this.checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('bandit-camp-enabled').addEventListener('change', function () {
|
function updateStatusBar(enabled) {
|
||||||
document.getElementById('bandit-toggle-hint').textContent = this.checked ? '🟢 Ενεργό' : 'Ανενεργό';
|
|
||||||
updateStatusBar(document.getElementById('farm-enabled').checked, this.checked);
|
|
||||||
});
|
|
||||||
|
|
||||||
function updateStatusBar(farmEnabled, banditEnabled) {
|
|
||||||
const bar = document.getElementById('status-bar');
|
const bar = document.getElementById('status-bar');
|
||||||
if (farmEnabled || banditEnabled) {
|
if (enabled) {
|
||||||
bar.className = 'status-bar visible';
|
bar.className = 'status-bar visible';
|
||||||
let msg = [];
|
bar.textContent = '🤖 Ο αυτόματος farmer είναι ενεργός. Το script θα λεηλατεί χωριά με τυχαίες καθυστερήσεις.';
|
||||||
if (farmEnabled) msg.push('Ο αυτόματος farmer είναι ενεργός.');
|
|
||||||
if (banditEnabled) msg.push('Το στρατόπεδο ληστών είναι ενεργό.');
|
|
||||||
bar.textContent = '🤖 ' + msg.join(' ') + ' Το script θα εκτελεί δράσεις με τυχαίες καθυστερήσεις.';
|
|
||||||
} else {
|
} else {
|
||||||
bar.className = 'status-bar visible off';
|
bar.className = 'status-bar visible off';
|
||||||
bar.textContent = '⏸ Οι αυτόματες ενέργειες είναι ανενεργές.';
|
bar.textContent = '⏸ Η αυτόματη λεηλασία είναι ανενεργή.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Save settings --
|
// -- Save settings --
|
||||||
function saveSettings() {
|
function saveSettings() {
|
||||||
const enabled = document.getElementById('farm-enabled').checked;
|
const enabled = document.getElementById('farm-enabled').checked;
|
||||||
const bandit_camp_enabled = document.getElementById('bandit-camp-enabled').checked;
|
|
||||||
fetch('/dashboard/farm-settings', {
|
fetch('/dashboard/farm-settings', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ player_id: PLAYER_ID, enabled, bandit_camp_enabled, loot_option: selectedOption })
|
body: JSON.stringify({ player_id: PLAYER_ID, enabled, loot_option: selectedOption })
|
||||||
})
|
})
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -391,13 +373,8 @@
|
|||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(cfg => {
|
.then(cfg => {
|
||||||
document.getElementById('farm-enabled').checked = cfg.enabled;
|
document.getElementById('farm-enabled').checked = cfg.enabled;
|
||||||
document.getElementById('bandit-camp-enabled').checked = cfg.bandit_camp_enabled || false;
|
|
||||||
|
|
||||||
document.getElementById('toggle-hint').textContent = cfg.enabled ? '🟢 Ενεργό' : 'Ανενεργό';
|
document.getElementById('toggle-hint').textContent = cfg.enabled ? '🟢 Ενεργό' : 'Ανενεργό';
|
||||||
document.getElementById('bandit-toggle-hint').textContent = cfg.bandit_camp_enabled ? '🟢 Ενεργό' : 'Ανενεργό';
|
if (cfg.enabled) updateStatusBar(true);
|
||||||
|
|
||||||
updateStatusBar(cfg.enabled, cfg.bandit_camp_enabled);
|
|
||||||
|
|
||||||
selectedOption = cfg.loot_option || 1;
|
selectedOption = cfg.loot_option || 1;
|
||||||
document.querySelectorAll('.option-btn').forEach(b => {
|
document.querySelectorAll('.option-btn').forEach(b => {
|
||||||
b.classList.toggle('selected', parseInt(b.dataset.option) === selectedOption);
|
b.classList.toggle('selected', parseInt(b.dataset.option) === selectedOption);
|
||||||
|
|||||||
Reference in New Issue
Block a user