Skip to content

Commit

Permalink
Feature: 0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
PassiveLemon committed Jan 15, 2025
1 parent f43d00e commit b3c9c65
Show file tree
Hide file tree
Showing 16 changed files with 3,721 additions and 193 deletions.
55 changes: 20 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,37 @@
# webfisher
A Nim based fishing script Webfishing

# TODO
- [x] Config loading
- [x] Find the true user (The user running with sudo)
- [x] Load config file
- [x] Create config file
- [x] Update config file
- [ ] Hot-reloading (just internally restart the program)
- [x] CLI
- [x] `-h | --help` (Print out other flags)
- [x] `-v | --version`
- [x] `-f | --file` (Config file to load)
- [x] `-d | --device` (Device for input)
- [x] mode argument (fish, bucket, or combo)
- [ ] Sensory
- [x] Capture screen and analyze pixels (X11 wrapper)
- [ ] Receive/send keyboard inputs (libevdev wrapper)
- [ ] Fishing game
- [ ] Casting/reeling
- [x] Game detection
- [ ] Game completion
- [ ] Bucket game
- [ ] Dumb mode (Periodically press "e")
- [ ] Combined game (fishing and bucket)
- [ ] Testing/ECC
- [ ] Error check config
- [ ] parse test constJson
- Other goals
- [ ] Variable verbosity output
A Nim based fishing script for Webfishing

> [!CAUTION]
> I am not responsible for any bans or data loss as a result of using this. This was a project for me to learn Nim. If you are worried about getting banned, don't use it and be a legitimate player :)
> I am not responsible for any bans or data loss as a result of using this. This was a project for me to learn Nim. If you have any concerns, don't use it and be a legitimate player :)
# Dependencies
- Linux. <b>This is not supported on Windows or MacOS.</b>
- X11. This is not supported on Wayland.
- Sudo. This requires access to input devices.
- Nim packages: `libevdev, x11`
- A user in the "input" group or sudo privileges.
- Nimble packages: `x11`

# Usage
### Nix:
- You can get the package in my [flake repository](https://github.com/PassiveLemon/lemonake). </br>
- You can get the package in my [flake repository](https://github.com/PassiveLemon/lemonake).
### Source:
- Clone the repo, cd to src
- Run `nim c -r webfisher`
- Edit the generated config file in your `~/.config/webfisher/config.json`. You can also supply a config file with `-f <path to config.json`. Please read the configuration below, you need to configure the file to enable functionality. </br>
- Edit the generated config file in your `~/.config/webfisher/config.json`. You can also supply a config file with `-f <path to config.json`.
- Arguments can be found by tacking `-h` or `--help`

In order to use this script, you must enable the built-in autoclicker in the Webfishing main settings.

# Configuration (config.json)
| Setting | Default | Details |
| :- | :- | :- |
| castOnStart | `false` (Boolean) | Whether to cast the rod upon starting the script. When set to `false`, this will not do anything until the rod is cast and the fishing task is detected. |
| castTime | `1.0` (Float) | How long to cast the rod (in seconds). |
| checkInterval | `0.25` (Float) | How often to check for visual input (in seconds). |

# TODO
- [ ] Timestamps
- [ ] Verbose and quiet output
- [ ] parse test constJson
- [ ] Periodic sodas (Player config for slot)
- [ ] Auto shop (Needs cursor movement)

4 changes: 3 additions & 1 deletion default.nix
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{ lib
, buildNimPackage
, libevdev
, xorg
}:
buildNimPackage (finalAttrs: {
pname = "webfisher";
version = "0.1.0";
version = "0.2.0";

src = ./.;

Expand All @@ -13,6 +14,7 @@ buildNimPackage (finalAttrs: {
lockFile = ./lock.json;

buildInputs = [
libevdev
xorg.libXext
];

Expand Down
6 changes: 4 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
devShells = {
default = pkgs.mkShell {
packages = with pkgs; [
nim nim_lk jq
nim
nim_lk jq
];
packagesFrom = [
self'.packages.default.nativeBuildInputs
Expand All @@ -34,7 +35,8 @@
};
};
packages = {
default = pkgs.callPackage ./default.nix { };
default = self'.packages.webfisher;
webfisher = pkgs.callPackage ./default.nix { };
};
};
};
Expand Down
12 changes: 0 additions & 12 deletions lock.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
{
"depends": [
{
"method": "fetchzip",
"packages": [
"libevdev"
],
"path": "/nix/store/l1cq6r7mnc3afvw8cc9bc87wpsvmc3mb-source",
"ref": "master",
"rev": "5dba39fe69c1b9a73aa9b911355860ba94c4d650",
"sha256": "1vrf50b8b79aqd583l1g3398gqx18v3j9l2liwwz6lmkb9ydvssy",
"srcDir": "",
"url": "https://github.com/luked99/libevdev.nim/archive/5dba39fe69c1b9a73aa9b911355860ba94c4d650.tar.gz"
},
{
"method": "fetchzip",
"packages": [
Expand Down
71 changes: 52 additions & 19 deletions src/webfisher.nim
Original file line number Diff line number Diff line change
@@ -1,37 +1,70 @@
import
std/os
std / [
os,
times
]

import
webfisher / [
config,
pixel
evdev,
screen,
task,
]

import
x11/xlib


type
GlobalState* = object
fishingGameActive: bool
bucketGameActive: bool
comboGameActive: bool
lineCast: bool
bucketTime: float
# sodaTime: float
# shopCount: int

var globalState*: GlobalState

block webfisher:
let
config: Config = initConfig()
display: PDisplay = XOpenDisplay(nil)
var globalState*: GlobalState = GlobalState(
lineCast: true,
bucketTime: epochTime(),
# sodaTime: epochTime(),
# shopCount: 0
)


echo config
echo "Config loaded."
block webfisher:
let config = initConfig()
if config.castOnStart == true:
globalState.lineCast = false
initDisplay()
initDevice()

while true:
echo "Simulated main loop"
if getFishingGame(display):
echo "Fishing game found"
sleep((config.checkInterval * 1000).int)
if (config.gameMode == "fish" or config.gameMode == "combo") and getFishingGame():
echo "Doing fishing task"
doFish()
sleep(3000)
if getCatchMenu():
echo "Clicking through menu"
clickCatchMenu()
else:
echo "No catch detected"
globalState.lineCast = false
sleep(1000)

if (config.gameMode == "bucket" or config.gameMode == "combo") and ((epochTime() - globalState.bucketTime) > 30) and globalState.lineCast == false:
echo "Doing bucket task"
doBucket()
sleep(1000)
if getCatchMenu():
echo "Clicking through menu"
clickCatchMenu()
else:
echo "No catch detected"
globalState.bucketTime = epochTime()
sleep(1000)

discard XCloseDisplay(display)
if globalState.lineCast == false:
sleep(1000)
echo "Casting line"
castLine(config.castTime)
globalState.lineCast = true

13 changes: 5 additions & 8 deletions src/webfisher/cli.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import
std/os,
std/strformat,
std/parseopt
std / [
os,
strformat,
parseopt
]

import
./meta
Expand All @@ -10,10 +12,8 @@ import
type
CliArgs* = object
file*: string
device*: string
mode*: string


proc cliHelp(): void =
echo """
Usage: webfisher [Options] [MODE]
Expand All @@ -25,7 +25,6 @@ Options:
-h, --help Show help and exit
-v, --version Show version and exit
-f=FILE, --file=FILE Location of the configuration file
-d=DEVICE, --device=DEVICE Input device to use
"""
quit(0)

Expand All @@ -48,8 +47,6 @@ proc processCliArgs*(): CliArgs =
cliVersion()
of "f", "file":
cliArgs.file = expandTilde(val)
of "d", "device":
cliArgs.device = val
of cmdEnd: assert(false)
return cliArgs

55 changes: 20 additions & 35 deletions src/webfisher/config.nim
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import
std/os,
std/strformat,
std/json
std / [
os,
strformat,
json
]

import
./cli


type
Config* = object
castOnStart*: bool
castTime*: float
checkInterval*: float
reelInterval*: float
reelTime*: float
resetTime*: float
inputDevice*: string
gameMode*: string


const
gameModes: seq[string] = @[ "fish", "bucket", "combo" ]
configJson: string = """
{
"castOnStart": false,
"castTime": 1.0,
"checkInterval": 0.5,
"reelInterval": 0.5,
"reelTime": 0.3,
"resetTime": 60.0
}
"""

Expand All @@ -39,7 +35,7 @@ proc getRealUserConfigDir(): string =
return getConfigDir() / "/webfisher/config.json"

proc createConfig(filePath: string): void =
let parentPath: string = parentDir(filePath)
let parentPath = parentDir(filePath)

if not existsOrCreateDir(parentPath):
try:
Expand All @@ -58,9 +54,9 @@ proc createConfig(filePath: string): void =

# Add missing keys from the configJson const to the host config
proc updateConfig(filePath: string): void =
let constConfig: JsonNode = parseJson(configJson)
let constConfig = parseJson(configJson)
var
hostConfig: JsonNode = parseFile(filePath)
hostConfig = parseFile(filePath)
hostRewrite: bool

for key, value in constConfig:
Expand All @@ -76,41 +72,30 @@ proc updateConfig(filePath: string): void =
echo "Could not update config file."

# Check and return parsed config
proc parseConfig(filePath: string, cliArgs: CliArgs): Config =
proc parseConfig(filePath: string; cliArgs: CliArgs): Config =
var
node: JsonNode = parseFile(filePath)
node = parseFile(filePath)
json: Config

# We can load CLI options into the programs config without writing them to the config file
if cliArgs.device == "":
node["inputDevice"] = %"/dev/input/event0"
else:
node["inputDevice"] = %cliArgs.device

if cliArgs.mode == "":
echo fmt"Argument MODE not provided. Defaulting to {gameModes[0]}..."
node["gameMode"] = %gameModes[0]
else:
if not gameModes.contains(cliArgs.mode):
echo fmt"{cliArgs.mode} is not a valid argument"
echo fmt"{cliArgs.mode} is not a valid argument."
quit(1)

node["gameMode"] = %cliArgs.mode

if node["castOnStart"].kind != JBool:
echo "config castOnStart is not a boolean."
quit(1)
if node["castTime"].kind != JFloat:
echo "config castTime is not a float"
echo "config castTime is not a float."
quit(1)
if node["checkInterval"].kind != JFloat:
echo "config castTime is not a float"
quit(1)
if node["reelInterval"].kind != JFloat:
echo "config reelInterval is not a float"
quit(1)
if node["reelTime"].kind != JFloat:
echo "config reelTime is not a float"
quit(1)
if node["resetTime"].kind != JFloat:
echo "config resetTime is not a float"
echo "config castTime is not a float."
quit(1)

try:
Expand All @@ -122,8 +107,8 @@ proc parseConfig(filePath: string, cliArgs: CliArgs): Config =
return json

proc initConfig*(): Config =
let cliArgs: CliArgs = processCliArgs()
var configDir: string = getRealUserConfigDir()
let cliArgs = processCliArgs()
var configDir = getRealUserConfigDir()

if cliArgs.file != "":
configDir = cliArgs.file
Expand Down
Loading

0 comments on commit b3c9c65

Please sign in to comment.