Jump to content

Leaderboard

Popular Content

Showing most liked content since 07/20/24 in all areas

  1. What are Tribot Scripters? Tribot scripters are members of the community who have demonstrated proficiency in writing scripts from all areas. They know the API, know how to create GUIs, know how to handle script arguments, and have the ability to create overall quality scripts and content. Regular scripters are still just community members that have provided at least one script for the community to use freely and have passed the application to become one. Premium Scripters are scripters who have successfully passed the application to get a script approved for sale. These members are official Tribot staff and contractors who have demonstrated not only technical capability, but also the ability to talk with customers, be friendly, and be helpful. They are capable of handling the responsibility of an official staff position and contract with our company. Benefits of becoming a Scripter Regular scripter rank provides free Tribot Premium Membership benefits (unlimited bots, use of community scripts, etc). They have access to upload scripts to our repository for community or even private usage. They also get access to a scripter+ only discord channel and forum where we collaborate on tribot as a whole and make decisions. Some regular scripters also get access to make some open source tribot contributions/fixes for their scripts to benefit from. Premium scripter rank provides all of that and the ability to sell their scripts on Tribot's marketplace and earn profits from them. Additionally, premium scripters get a larger say in how we operate and conduct business. They get access to all semi-open-source tribot code and can apply directly to be a Tribot client/web developer. How to become a Scripter In order to become a scripter, you must write at least one script that you plan on releasing publicly to the community script repository on Tribot. For writing scripts, you can find tutorials in this section. At least one of these scripts must contain the following: A GUI (Swing, JavaFX, or Jetpack Compose) Script arg handling Complex enough to be somewhat configurable (a simple one-location iron miner is not enough, but an AIO miner that supports 10 locations could be) From there, you can apply by creating a support ticket in this section with the following: An upload of your script source code (github link, zip file, etc) Why you want to become a scripter Any additional content you've created for Tribot (guides, open source scripts, helpful advice you've given) We will take into consideration your script, code, and general community conduct. Scripter applications may get delayed based on availability and/or the need for more scripters. For premium scripter, you can contact me directly after you have become a scripter and we can discuss what you can do to become premium. This is usually just writing a premium script, but the content matters depending on our need and the market. It also depends on your eligibility to be a contractor.
    2 likes
  2. Hello everybody! We're diving into the world of mouse paints and mouse splines. We'll cover what the code is doing, the data structures it's using (hello, circular buffer!), why aiming for 50fps is crucial, and some Big O notation(O(1) to be precise). Let's get painting. What the Code is Doing Our tutorial involves creating and managing various mouse paints, which help us visualize mouse movements and clicks. We have different styles of mouse paints, such as MouseCursorPaint, OriginalMouseCursorPaint, and PlusSignMouseCursorPaint. These classes define how the mouse movements are drawn on the screen. Here's a brief overview of the core components: MouseCursorPaintConfig: Configures the size, colors, and gradients used in the mouse paints. PolymorphicMousePaint: An interface for mouse paint implementations with an additional ripple effect control. MouseCursorPaint, OriginalMouseCursorPaint, PlusSignMouseCursorPaint: Implementations of PolymorphicMousePaint that define different styles of mouse paints. MouseRipple and MouseRipplePaintConfig: Handle the ripple effects when the mouse is clicked. MousePaintThread: The thread that manages the painting of mouse trails and handles the ripple effects. Data Structures: Circular Buffer (Infinite Memory!) A significant part of our implementation uses a circular buffer. Imagine a circular buffer as a conveyor belt with a fixed number of items allowed on it (15 in our case). You add mouse positions in order, and when you run out of space, you go back to the first point and overwrite it. This way, we always keep the latest 15 mouse positions without running out of "memory." Circular Buffer Benefits: Efficiently Manages a Fixed Number of Elements: The buffer maintains a set number of elements (like our 15 mouse positions), ensuring we use a consistent amount of memory. Old Data is Automatically Discarded: As new data comes in, old data is overwritten, keeping the buffer fresh with the latest entries without any manual cleanup. Constant Time Complexity, O(1): Adding, updating, and removing elements in a circular buffer is extremely efficient, as each operation takes a constant amount of time regardless of the buffer size. Extremely Efficient: Circular buffers are known for their efficiency in managing fixed size datasets, making them perfect for real time applications like our mouse trail system. Why 50 FPS? In our mouse paint thread, we're aiming for 50 frames per second (fps). Why? Because smooth visuals matter. At 50fps, the mouse paint animations look fluid and responsive. Here's the math: Tick Rate Calculation: tickRate = 1 second / fps For 50 fps: tickRate = 1000ms / 50fps = 20ms This means our thread updates every 20 milliseconds, ensuring we maintain that buttery smooth animation. Why Delta Time (dt)? When implementing fade effects, it’s crucial to ensure that the animation progresses smoothly and consistently across different frame rates. This is where delta time (dt) comes into play. What is Delta Time (dt)? Delta time (dt) represents the time elapsed between the current frame and the previous frame. By using dt, we can adjust our animations based on the actual time that has passed, rather than relying on a fixed time step. Benefits of Using Delta Time: Frame Rate Independence: Without dt: If the frame rate drops (e.g., from 50 fps to 30 fps), animations would appear slower because the fixed time step remains the same. With dt: The animation speed remains consistent because it adjusts according to the time elapsed between frames. Smooth Animations: Using dt ensures that fade effects (or any time based animations) proceed at the same pace regardless of frame rate fluctuations, leading to smoother transitions and a more polished user experience. The Big O Notation: O(1) In our circular buffer, adding, updating and removing elements have a time complexity of O(1). This means these operations take a constant amount of time, regardless of the buffer size. This efficiency is key for maintaining high performance in real time applications like our mouse point system. Differences in Mouse Paints MouseCursorPaint: Rotates an arc around the mouse position with a gradient and dynamic stroke width. Can activate a ripple effect for click feedback. OriginalMouseCursorPaint: Draws simple cross lines (TRiBot classic). No fancy effects, just the basics. PlusSignMouseCursorPaint: Draws a plus sign at the mouse position. Focuses on clear, precise indicators. The Spline Trail Magic Now, let's talk about drawing those smooth, sleek, and sexy trails using quadratic bézier curves. This is where the real fun begins. We use the MousePaintThread class to handle everything from mouse clicks to drawing the trails. Here’s a quick tour of the important bits: Circular Buffer: Our spline trail is stored using a circular buffer (arrays xPoints, yPoints, colors, head, tail) Quadratic Bézier Curves: When drawing the trail, we use quadratic bézier curves. This math magic helps us create smooth sexy curves between points. Here’s how it works: Points & Path: We keep track of mouse positions in arrays (xPoints, yPoints). These points form the backbone of our trail. GeneralPath: This is where the magic happens. We use a GeneralPath object to draw smooth curves. For each segment of the trail, we move from one point to the next, creating a quadratic bézier curve in between. Curving It Up: We call quadTo() on the GeneralPath to draw curves. It takes three points: the starting point, a control point that determines the curve’s direction, and the ending point. The result? Buttery smooth trails that look like you’re painting with the damn wind! class MousePaintThread( private var mouseSplinePaintConfig: MouseSplinePaintConfig = MouseSplinePaintConfig(), private var mouseCursorPaintConfig: MouseCursorPaintConfig = MouseCursorPaintConfig(), private var mouseRipplePaintConfig: MouseRipplePaintConfig = MouseRipplePaintConfig(), private var mouseCursorPaint: PolymorphicMousePaint = MouseCursorPaint(mouseCursorPaintConfig) ) : Thread("Mouse Paint Thread"), Consumer<Graphics2D>, MouseClickListener { private val maxPoints = 15 private val xPoints = IntArray(maxPoints) private val yPoints = IntArray(maxPoints) private val colors = IntArray(maxPoints) { mouseSplinePaintConfig.trailColor.rgb } private val trailPath = GeneralPath() private var pointCount = 0 private var head = 0 private var tail = 0 private var lastMouseX = -1 private var lastMouseY = -1 private var lastUpdateTime = currentTimeMillis() private val ripples = synchronizedList(mutableListOf<MouseRipple>()) private var clickCount = 0 fun configure( mouseCursorPaintConfig: MouseCursorPaintConfig, mouseSplinePaintConfig: MouseSplinePaintConfig, mouseRipplePaintConfig: MouseRipplePaintConfig, polymorphicMousePaint: PolymorphicMousePaint ) { this.mouseCursorPaintConfig = mouseCursorPaintConfig this.mouseSplinePaintConfig = mouseSplinePaintConfig this.mouseRipplePaintConfig = mouseRipplePaintConfig this.mouseCursorPaint = polymorphicMousePaint setMousePaint(this.mouseCursorPaint) } override fun mouseClicked( point: Point, mouseButton: Int, isBot: Boolean ) { val color = when (clickCount) { 0 -> mouseRipplePaintConfig.rippleColorOne 1 -> mouseRipplePaintConfig.rippleColorTwo else -> mouseRipplePaintConfig.rippleColorThree } addRipple(MouseRipple(center = point, color = color)) // Reset after 3 ripples clickCount = (clickCount + 1) % 3 } override fun run() { addMouseClickListener(this) addPaint(this) setMousePaint(mouseCursorPaint) setMouseSplinePaint { _, _ -> } while (true) { // We want 50 fps (max limit) wait(20) val currentTime = currentTimeMillis() val deltaTime = currentTime - lastUpdateTime val mousePos = getPos() addPoint(mousePos.x, mousePos.y) fadeEffect(deltaTime) synchronized(ripples) { val iterator = ripples.iterator() while (iterator.hasNext()) { mouseCursorPaint.isRippleActive = true val ripple = iterator.next() if (ripple.expanding) { ripple.radius += 4 ripple.alpha -= 8 if (ripple.radius >= 50) { // When the radius reaches 50, start contracting ripple.expanding = false } } else { ripple.radius -= 4 ripple.alpha += 8 if (ripple.radius <= 5 || ripple.alpha >= 255) { // When the radius is too small, or alpha is back to max, remove iterator.remove() mouseCursorPaint.isRippleActive = false } } } } lastUpdateTime = currentTime } } override fun accept(g2: Graphics2D) = draw(g2) private fun addRipple(ripple: MouseRipple) = synchronized(ripples) { ripples.add(ripple) } private fun addPoint(x: Int, y: Int) { // Mouse hasn't moved, so don't add a new point if (x == lastMouseX && y == lastMouseY) return // Update last mouse position lastMouseX = x lastMouseY = y xPoints[head] = x yPoints[head] = y colors[head] = mouseSplinePaintConfig.trailColor.rgb head = (head + 1) % maxPoints if (pointCount < maxPoints) { pointCount++ } else { tail = (tail + 1) % maxPoints } } private fun fadeEffect(deltaTime: Long) { // Ensure a minimum fade amount val fadeAmount = (deltaTime * 10 / 50).coerceAtLeast(1) for (i in 0 until pointCount) { val index = (tail + i) % maxPoints val currentAlpha = colors[index] ushr 24 val newAlpha = (currentAlpha - fadeAmount).coerceIn(0, 255) colors[index] = (((newAlpha shl 24) or (colors[index] and 0x00FFFFFF).toLong()).toInt()) } } private fun draw(g: Graphics2D) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) if (pointCount >= 3) { // IMPORTANT: Reset the path before iteration trailPath.reset() for (i in 0 until pointCount - 2) { val index = (tail + i) % maxPoints val nextIndex = (index + 1) % maxPoints trailPath.moveTo(xPoints[index].toFloat(), yPoints[index].toFloat()) val midX = (xPoints[index] + xPoints[nextIndex]) / 2f val midY = (yPoints[index] + yPoints[nextIndex]) / 2f trailPath.quadTo(midX, midY, xPoints[nextIndex].toFloat(), yPoints[nextIndex].toFloat()) val color = Color(colors[index], true) val nextColor = Color(colors[nextIndex], true) val gradient = GradientPaint(xPoints[index].toFloat(), yPoints[index].toFloat(), color, midX, midY, nextColor) g.paint = gradient g.draw(trailPath) trailPath.reset() } } synchronized(ripples) { for (ripple in ripples) { g.color = Color(ripple.color.red, ripple.color.green, ripple.color.blue, ripple.alpha) g.drawOval( ripple.center.x - ripple.radius.toInt(), ripple.center.y - ripple.radius.toInt(), (ripple.radius * 2).toInt(), (ripple.radius * 2).toInt() ) } } } } Wrapping Up Congratulations! You've successfully transformed simple mouse movements into visually captivating trails using circular buffers, quadratic bézier curves, and smooth animations. Remember, this is just the beginning. Feel free to experiment with different colors, sizes, and effects to tailor the visuals to your unique style. Happy coding, and may your mouse trails always be smooth and sexy! Github: https://github.com/its-jackson/tribot-mouse-paints
    1 like
  3. Having script trials would give customers self-service to determine if a script fits their needs (think about how much you hate using software that doesn't have some sort of self-service). This improves customer experience and reduces support required for scripters to answer basic questions about script functionality. It would also likely reduce refund requests. Trials should be customizable by the script author, they should be able to choose the duration, or even choose to not offer trials at all. Trials should ideally also be locked behind TRiBot VIP. The trial system on the original repository before the Shopify switch worked great and fit all needs.
    1 like
  4. So I believe what happened with the planks is when I initially built the oak lard the gui preset function decided to put teak lard on accident. Possibly the bot was trying to get teak planks unnoted. Things seems to be running smooth as of now so thank you. Also thank you for the max instances information. Was always only running one tab and ending each client after usage. So possibly I needed to wait a little longer between ending and starting another script again
    1 like
  5. Script is a bit dumb in the sense that buying from the shop, the bank is on my screen (in resizable mode) yet it will close the interface using the X then click the minimap to walk to the bank when it could literally just go from shop to bank in one click.
    1 like
×
×
  • Create New...