Skip to main content
Profiles is a Packet Utils tab in the shared n3 sidebar. It stores account credentials in an encrypted profile store, applies them to the login screen, and manages per-profile proxy and world preferences.

What you can do from the tab

  • Add, edit, delete, and unlock profiles
  • Trigger a login through the Jagex OAuth flow in your system browser
  • Bulk import profiles by pasting typed rows
  • Add, edit, delete, and test saved SOCKS5 proxies
  • Set a preferred world or world type per profile
The tab also embeds a filtered RuneLite configuration panel that renders Auto Login and the secret Unlock Password field from the n3profiles group.

Architecture

Credential storage

ProfileStore derives an AES key from your unlock password with PBKDF2WithHmacSHA256 (100,000 iterations, 128-bit keys) and encrypts the profile blob with AES-GCM under the n3profiles group (profilesData plus salt). Its only dependency is the RuneLite ConfigManager, so other plugins can inject their own instance and read the same store without a shared singleton. Profile lines are typed:
Untyped legacy lines (label:login:password[:pin]) decode as LEGACY and re-encode on first load.

Store API

  • load(char[] password) decrypts, migrates, and parses profiles. Throws on a wrong password.
  • save(List<StoredProfile>, char[] password) re-encrypts and persists.
  • loadWithConfiguredPassword() decrypts with the configured unlock password and returns an empty list on any failure instead of throwing.
  • hasConfiguredPassword() reports whether auto-unlock is configured.
The plugin never persists, logs, serializes, or screenshots the supplied password.

Bulk import

Unlock the Profiles tab and select Bulk Import to paste multiline input. The importer accepts only typed rows:
Rules the importer enforces:
  • Blank lines are ignored.
  • Legacy rows require a login and password. The PIN must be blank or exactly four digits.
  • Jagex rows require a character ID and session ID. The user hash is optional.
  • Preferred worlds must be non-negative integers.
  • World types must be MEMBERS, F2P, PVP, or blank.
Malformed rows and duplicate labels are skipped and reported in the import summary.

Saved proxies

Saved proxies live in the n3proxies config group with their own random salt but share the active profiles unlock password. The unlocked tab can add, edit, delete, and test uniquely labelled SOCKS5 proxies. A test performs a real SOCKS5 negotiation, optional username/password authentication, and a tunneled connection request on a background executor. Deleting a proxy also clears profile references to its label.

Login behavior

ProfileLoginService applies two profile kinds:
  • applyLegacyProfile(username, password, autoLogin) sets the client username and password fields and dispatches Enter keys when autoLogin is on. A client already on the legacy login form is left as-is.
  • applyJagexProfile(sessionId, characterId, displayName) applies a Jagex session through the reflection adapter, selects login index 10, and attempts the shared welcome-screen continue helper. It throws ReflectiveOperationException when the hooks are unavailable.
  • resetToLegacyLogin() reverts a Jagex login screen to the legacy form. This is the only path that performs the Jagex-to-legacy transition, so a client already in legacy mode is never reset.
  • isJagexLoginAvailable() probes adapter support.
The adapter validates cached field shapes against the injected class loader before use and rolls back every reflected field if a transition fails. Missing, ambiguous, or unsafe login-index hooks make the adapter unsupported. Applying a profile that names a saved proxy immediately replaces global proxy routing. A preferred world is selected on the login screen before credentials are submitted. With no explicit world, a non-empty world-type preference selects the first matching world-list entry. An explicit world that conflicts with the configured type is rejected.
Set the Unlock Password field if you want profiles available without manual unlock, for example for auto-login. Leaving it blank requires unlocking the tab by hand each session.