AI-Generated HUDchat Bot Code; for those interested...

SDK, Bots and Programming
Post Reply
User avatar
OldChineeseMan
Posts: 11
Joined: Sat Dec 16, 2023 3:49 am

AI-Generated HUDchat Bot Code; for those interested...

OCM's HUDchat Bot

Image

Just an interesting novelty... feel free to use it to learn, add to it, laugh at the terrible coding, or whatever you may like.

I am not a programmer. This code was generated by feeding ChatGPT-4 the Greeter bot and Midi DJ bot examples, letting it examine the header file, then asking it to extrapolate from there with fresh code to add/remove features. I fed the compiling errors back to GPT until things worked.

Image

The bot is started through a command prompt (in windows, type "cmd" in your taskbar search). Change directory to wherever you put the files (if you put it in drive C:\bots, type "CD C:\bots" to change to the "bots" directory). Then type the name of the exe file, your citizen number, your privilege password, and the world name to enter, all separated by spaces (I'm citizen 27, I set my privilege password to 12345, and I want the bot to enter the world BigChillin, so I would type "DWbot1.exe 27 12345 BigChillin").

Users can print messages to the screen for everyone within range of the bot to see. To do so just whisper your message to HUDchat bot. Users can whisper "/clear" to the bot to clear the chat messages from the screen. The greeting/farewell messages can be enabled by removing the // in front of the lines of code "Say Hello" and "Say Bye". They are off by default, since most people have a greeter bot anyway.

Download: https://arcticice.net/Nosferatu/zips/HUDchat_v1.zip

Code: Select all

#define AW_NO_FUNCTION_MAPPING // for UTF-8 or older single-byte and multi-byte character sets

#include <windows.h>
#include "reasons.h"
#include "aw.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_AVATARS_IN_SCENE 35
#define MAX_HUD_LINES 10
#define MAX_LINE_LENGTH 50
#define MAX_HUD_LINE_LINES 5
#define HEARTBEAT_INTERVAL 30

struct AVATAR
{
    int session;
    char name[18];
};

struct HUD_LINE
{
    int id;
    int num_lines;
    char lines[MAX_HUD_LINE_LINES][MAX_LINE_LENGTH + 1];
};

struct AVATAR avatars[MAX_AVATARS_IN_SCENE];
struct HUD_LINE hud_lines[MAX_HUD_LINES];

void handle_avatar_add(void);
void handle_avatar_delete(void);
void handle_address(int rc);
void handle_chat(void);
void update_hud_messages(void);
void wrap_line(const char* line, struct HUD_LINE* hud_line, int max_line_length);
void send_heartbeat(void); // Prototype heartbeat function, keeps bot from timing out

int main(int argc, char* argv[])
{
    int rc;

    // Check command line
    if (argc < 4)
    {
        printf("To begin type: DWbot1.exe cit-number password world\n", argv[0]);
        return 1;
    }

    // Initialize Delta Worlds API
    rc = aw_init(AW_BUILD);
    if (rc != RC_SUCCESS)
    {
        printf("Unable to initialize API (reason %d)\n", rc);
        return 1;
    }

    // Variable to track last heartbeat time
    time_t last_heartbeat = time(NULL);

    // Install handler for avatar_add, avatar_delete, and chat events
    aw_event_set(AW_EVENT_AVATAR_ADD, handle_avatar_add);
    aw_event_set(AW_EVENT_AVATAR_DELETE, handle_avatar_delete);
    aw_event_set(AW_EVENT_CHAT, handle_chat);

    /* Install callback for aw_address */
    aw_callback_set(AW_CALLBACK_ADDRESS, handle_address);

    /* create bot instance */
    if ((rc = aw_create("auth.deltaworlds.com", 6670, 0)) != 0) {
        printf("Unable to create bot instance (reason %d)\n", rc);
        exit(1);
    }

    // Log bot into the universe
    aw_int_set(AW_LOGIN_OWNER, atoi(argv[1]));
    aw_string_set(AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]);
    aw_string_set(AW_LOGIN_APPLICATION, "OCMBOTv1");
    aw_string_set(AW_LOGIN_NAME, "HUDchat");
    rc = aw_login();
    if (rc != RC_SUCCESS)
    {
        printf("Unable to login (reason %d)\n", rc);
        return 1;
    }

    // Enter bot into the world
    rc = aw_enter(argv[3]);
    if (rc != RC_SUCCESS)
    {
        printf("Unable to enter world (reason %d)\n", rc);
        return 1;
    }

    // Announce position in the world
    aw_int_set(AW_MY_X, 1000); // 1W
    aw_int_set(AW_MY_Z, -7000); // 7S
    aw_int_set(AW_MY_YAW, 2250); // Face towards GZ
    rc = aw_state_change();
    if (rc != RC_SUCCESS)
    {
        printf("Unable to change state (reason %d)\n", rc);
        return 1;
    }

    // Main event loop
    while (aw_wait(-1) == RC_SUCCESS) {
        if (difftime(time(NULL), last_heartbeat) >= HEARTBEAT_INTERVAL) {
            send_heartbeat();
            last_heartbeat = time(NULL); // Update the last heartbeat time
        }

        // Close everything down
        aw_destroy();
        aw_term();

        return 0;
    }
}

void send_heartbeat() {
    // Heartbeat function - sends clear command to chat to keep from timing out.
    aw_say("/clear");
}

void handle_avatar_add(void)
{
    int i;
    int rc;

    // Add avatar to the scene
    for (i = 0; i < MAX_AVATARS_IN_SCENE; i++)
    {
        if (avatars[i].session == 0)
        {
            avatars[i].session = aw_int(AW_AVATAR_SESSION);
            strcpy(avatars[i].name, aw_string(AW_AVATAR_NAME));
            break;
        }
    }
    aw_address(aw_int(AW_AVATAR_SESSION));


    // Say Hello (remove slashes from the following lines to enable greeting message) //
  
  //  char message[100];
  //  static char avatar_name[AW_MAX_ATTRIBUTE];
  //  strcpy(avatar_name, aw_string(AW_AVATAR_NAME));
  //  sprintf(message, "Ahoy there %s!", avatar_name);
  //  aw_say(message);
}

void handle_avatar_delete(void)
{
    int i;

    // Remove avatar from the scene
    for (i = 0; i < MAX_AVATARS_IN_SCENE; i++)
    {
        if (avatars[i].session == aw_int(AW_CHAT_SESSION))
        {
            avatars[i].session = 0; // Mark struct as unused
            strcpy(avatars[i].name, "");
            break;
        }
    }


    // Say Bye (remove slashes from the following lines to enable farewell message) //
   
   // char message[100];
   // static char avatar_name[AW_MAX_ATTRIBUTE];
   // strcpy(avatar_name, aw_string(AW_AVATAR_NAME));
   // sprintf(message, "Bye, %s!", avatar_name);
   // aw_say(message);
}

void handle_address(int rc)
{
    /* Keep in mind that AW_AVATAR_NAME is not defined within the context of this callback */

    int i;
    char hud_message[100];
    char name[256];
    char msg[256];

    strcpy(name, "<UNKNOWN>");

    /* Find name of the avatar */
    for (i = 0; i < MAX_AVATARS_IN_SCENE; i++)
    {
        if (avatars[i].session == aw_int(AW_AVATAR_SESSION))
        {
            strcpy(name, avatars[i].name);
            break;
        }
    }

    if (rc != RC_SUCCESS)
    {
        sprintf(msg, "%s, I cannot determine your IP address (reason %d)", name, rc);
    }
    else
    {
        int           address;
        unsigned char* p = (unsigned char*)&address;

        address = aw_int(AW_AVATAR_ADDRESS);

        /* The address is in network byte order which means that the most significant byte comes first in memory */
        sprintf(hud_message, "%s [%u.%u.%u.%u] enters", name, p[0], p[1], p[2], p[3]);

        /* log the event to the console */
        printf("[%u.%u.%u.%u] %s entered chat.\n", p[0], p[1], p[2], p[3], name);

        // Shift up old messages etc
        for (i = 0; i < MAX_HUD_LINES - 1; i++)
        {
            hud_lines[i].id = hud_lines[i + 1].id;
            hud_lines[i].num_lines = hud_lines[i + 1].num_lines;
            for (int j = 0; j < hud_lines[i].num_lines; j++)
            {
                strcpy(hud_lines[i].lines[j], hud_lines[i + 1].lines[j]);
            }
        }
        hud_lines[MAX_HUD_LINES - 1].id = 0; // We don't need the session ID for this message
        wrap_line(hud_message, &hud_lines[MAX_HUD_LINES - 1], MAX_LINE_LENGTH);

        // Update HUD messages
        update_hud_messages();
    }
}


void handle_chat(void)
{
    char message[301];
    static char avatar_name[AW_MAX_ATTRIBUTE];
    strcpy(avatar_name, aw_string(AW_AVATAR_NAME));

    // Check for the "/clear" command
    if (strcmp(aw_string(AW_CHAT_MESSAGE), "/clear") == 0)
    {
        // Clear HUD
        for (int i = 0; i < MAX_HUD_LINES; i++)
        {
            hud_lines[i].id = 0;
            hud_lines[i].num_lines = 0;
        }

        // Display "Chat cleared" message
        wrap_line("Chat cleared", &hud_lines[MAX_HUD_LINES - 1], MAX_LINE_LENGTH);
    }
    else
    {
        // Handle normal chat messages
        snprintf(message, 300, "%s: %s", avatar_name, aw_string(AW_CHAT_MESSAGE));

        // Shift up old messages
        for (int i = 0; i < MAX_HUD_LINES - 1; i++)
        {
            hud_lines[i].id = hud_lines[i + 1].id;
            hud_lines[i].num_lines = hud_lines[i + 1].num_lines;
            for (int j = 0; j < hud_lines[i].num_lines; j++)
            {
                strcpy(hud_lines[i].lines[j], hud_lines[i + 1].lines[j]);
            }
        }

        // Check if the chat message starts with "/me" and remove for action
        if (strncmp(aw_string(AW_CHAT_MESSAGE), "/me", 3) == 0) {
            snprintf(message, 300, "%s %s", avatar_name, aw_string(AW_CHAT_MESSAGE) + 4); // +4 to remove the "/me " from the message
        }
        hud_lines[MAX_HUD_LINES - 1].id = aw_int(AW_CHAT_SESSION);
        wrap_line(message, &hud_lines[MAX_HUD_LINES - 1], MAX_LINE_LENGTH);
    }

    // Update HUD messages
    update_hud_messages();
}


void wrap_line(const char* line, struct HUD_LINE* hud_line, int max_line_length)
{
    const char* line_end = line + strlen(line);
    const char* line_start = line;
    hud_line->num_lines = 0;

    while (line_start < line_end && hud_line->num_lines < MAX_HUD_LINE_LINES)
    {
        const char* line_break = line_start + max_line_length;
        if (line_break > line_end)
        {
            line_break = line_end;
        }
        else
        {
            while (line_break > line_start && *line_break != ' ')
            {
                line_break--;
            }
            if (line_break == line_start)
            {
                line_break = line_start + max_line_length;
            }
        }

        strncpy(hud_line->lines[hud_line->num_lines], line_start, line_break - line_start);
        hud_line->lines[hud_line->num_lines][line_break - line_start] = '\0';
        hud_line->num_lines++;

        line_start = line_break;
        while (*line_start == ' ')
        {
            line_start++;
        }
    }
}



void update_hud_messages(void)
{
    int rc;

    // Destroy old HUD elements
    for (int i = 0; i < MAX_HUD_LINES; i++)
    {
        for (int j = 0; j < MAX_HUD_LINE_LINES; j++)
        {
            aw_hud_destroy(0, i * MAX_HUD_LINE_LINES + j + 1);
        }
    }

    // Create new HUD elements
    int y_offset = 0;
    for (int i = 0; i < MAX_HUD_LINES; i++)
    {
        for (int j = 0; j < hud_lines[i].num_lines; j++)
        {
            // create the HUD element
            aw_int_set(AW_HUD_ELEMENT_TYPE, AW_HUD_TYPE_TEXT);
            aw_string_set(AW_HUD_ELEMENT_TEXT, hud_lines[i].lines[j]);
            aw_int_set(AW_HUD_ELEMENT_ID, y_offset + 1);
            aw_int_set(AW_HUD_ELEMENT_SESSION, 0);
            aw_int_set(AW_HUD_ELEMENT_ORIGIN, AW_HUD_ORIGIN_TOP_LEFT);
            aw_float_set(AW_HUD_ELEMENT_OPACITY, 1.0f);
            aw_int_set(AW_HUD_ELEMENT_X, -64);
            aw_int_set(AW_HUD_ELEMENT_Y, 50 + y_offset * 28); // Adjust the spacing between lines
            aw_int_set(AW_HUD_ELEMENT_Z, 1);
            aw_int_set(AW_HUD_ELEMENT_FLAGS, AW_HUD_ELEMENT_FLAG_CLICKS);
            aw_int_set(AW_HUD_ELEMENT_SIZE_X, 800);
            aw_int_set(AW_HUD_ELEMENT_SIZE_Y, 30); // Increase the text size
            aw_int_set(AW_HUD_ELEMENT_FLAGS, AW_HUD_ELEMENT_FLAG_TRANSITION | true);

            // Set the color to green for the IP address and name announcement message
            if (strstr(hud_lines[i].lines[j], "enters") != NULL && strstr(hud_lines[i].lines[j], "[") != NULL && strstr(hud_lines[i].lines[j], "]") != NULL) {
                aw_int_set(AW_HUD_ELEMENT_COLOR, 0x00FF00); // Green color
            }
            else {
                aw_int_set(AW_HUD_ELEMENT_COLOR, 0xFFFFFF); // White color
            }

            rc = aw_hud_create();
            if (rc != RC_SUCCESS)
            {
                printf("Unable to create HUD element (reason %d)\n", rc);
            }

            y_offset++;
        }
    }
}
~OCM =p
Post Reply