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.
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++;
}
}
}