Python INTERPRETER

Hi Ruri,

I am implementing scripts in the new Python block introduced in v2.0.0. After performing deep introspection inside the CPython debugger, I verified that the Source Generator (CSnakes) compiles the block code inside a clean asynchronous coroutine: async def __ob2_entry__() with co_argcount = 0, co_freevars = (), and a completely isolated globals() dictionary.

Given that the credentials (USER, PASS) and the bot state (BotData) are not being injected via function arguments, lexical scope (closures), or global variables:

What is the exact physical mechanism designed in RuriLib to establish communication between the .NET host and CPython? Is there an interop extension module registered in sys.modules, or perhaps proxy functions injected into builtins to handle get/set operations for the bot variables?

I would highly appreciate a real code snippet demonstrating the correct way to extract the current username and save a capture from inside this coroutine.


:handshake::handshake::handshake:

BLOCK:ConstantString
value = @input.PASS
=> VAR @password
ENDBLOCK

BLOCK:Script
INTERPRETER:Python
INPUT password
BEGIN SCRIPT
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization import load_pem_public_key
import base64

public_key_pem = b"“”-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApW91T4TEaN280cXwo6LP
jkYxkOXdxQHXPwoXwk3UtCI2smnNcl/9KK+pc6XZ3ROqsvrrLrub1lM5n0uKfNQg
omobEucBQ8sWCDE0ltkwoSIuIAuvv9yOXi8ICAu9DLPyHcIL108+jV0cIWHCj2u0
/LjtnYLFO0FFFw+k4TpQtXvED2nWDFXapSHT3MA271fwpq3sr778k9SWP0sLuV1W
eCpNGtBPNVEYq8axmT7PilyvAFd5qML4sJQpGyfAZIbXtUkZ8lHd1esFe7zuR5XL
8rRrxlcvjMHnIfVCWXmoV0B91Dh5dEuFkxrx0z/VpBoWoC6r6Z0HJ3LaBCmNQLWL
mQIDAQAB
-----END PUBLIC KEY-----“”"

public_key = load_pem_public_key(public_key_pem)

encrypted = public_key.encrypt(
password.encode(“utf-8”),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)

encryptedSHA256 = base64.b64encode(encrypted).decode(“utf-8”)
END SCRIPT
OUTPUT String @encryptedSHA256
ENDBLOCK Sliced [email protected]:fresamarga2231 into:

USERNAME: [email protected]

PASSWORD: fresamarga2231

USER: [email protected]

PASS: fresamarga2231

Constant String (ConstantString) <<

Set constant value [email protected]

Assigned value to variable ‘username’

Constant String (ConstantString) <<

Set constant value fresamarga2231

Assigned value to variable ‘password’

Script (InvokePythonAsync) <<

Executed Python script with result: {encryptedSHA256 = pQNX4560dGgFhvbzzZQ7lccsv87x0QeVoLNgTPsixeaJPsgVpkL/JrS0pthkju071RsM6OIE57ma54xs4gCUdQQQLZP73MfiZqarl3rLLqpu9ElPs8TxRIFUueiq9Kn7YtG+8NKIRvqOsIvaNjFQakJ5ZgWgEz57Oujhe5tGzImGiunI9Ae58wLMDkDUprkF+mhSbIdkuoBJarZDw/9Vk4ENl9YXvE36n4Ds+3wulpD/WoP1z7mSodHvVxZgOoCKz+rvY0Wig5v5g0DhXya/DM3mya+fsfbNBOEBHbkP6Cr1Zdvv6bwdt3t+kXu/SWIMZg3DWOaPl7n7UMWVGY8ycg==}

Assigned value to variable ‘encryptedSHA256’

BOT ENDED AFTER 682 ms WITH STATUS: NONE

Hello,

it’s not CSnakes doing what you mentioned, but some custom code I added to make passing inputs and extracting outputs easier for OB2.

You would need to set data.USER and data.PASS as variables (e.g. using a constant string block) and then pass them as inputs to the python script, that way they are available in there.

You can find an example here Interoperability | OpenBullet 2

In your case I would do something like

BLOCK:ConstantString
  value = @input.USERNAME
  => VAR @username
ENDBLOCK

BLOCK:ConstantString
  value = @input.PASSWORD
  => VAR @password
ENDBLOCK

BLOCK:Script
INTERPRETER:Python
INPUT username,password
BEGIN SCRIPT
result = f"{username}-{password}"
END SCRIPT
OUTPUT String @result
ENDBLOCK

CLOG SkyBlue @result

Also remember to use async stuff in your python code (so, for example, don’t use requests but use libs like httpx or aiohttp, anything you can await) otherwise bots will be extremely slow as there is just 1 interpreter for everything.

3 Likes