16 Commits

Author SHA1 Message Date
Rumble
5024dd8e66 Updated for 2025 release 2025-01-09 23:57:59 +00:00
Thomas Arp
69888a5d89 Update aedit.c (#145)
fixes #144 

Thanks to @gbstott for the bug report
2025-01-08 22:57:39 +01:00
haloway13
1ccb6adaee Update dg_olc.c (#143)
Better auto-formatting of dg_scripts. Thanks to haloway13 for the patch.
2025-01-01 11:05:54 +01:00
Thomas Arp
d3227f1300 Fix bug in process_output (#140)
Based on error report from JTP in the tbamud forums. If an attacker was able to start a session and then break the connection, the  process_output function would fail. This would trigger two calls to close_socket on the same descriptor. This in turn results in a double free on the character struct.

https://www.tbamud.com/kunena/4-development/5617-another-core-dump-not-long-after-the-one-earlier
Thanks to JTP for the bug report.
2024-12-30 12:30:29 +01:00
Thomas Arp
88b3027ec6 Bugfix/135 while freezes the mud (#138)
* Added loop counter per while instead of global. fixes #135

* Revert "Added loop counter per while instead of global. fixes #135"

This reverts commit 59cf6a1fb2.

* Remove extraneous reset of loop var.

Fixes #135

Thanks to bylins for the fix - https://github.com/bylins
2024-09-28 20:29:11 +02:00
Victor Augusto Borges Dias de Almeida
7036a15782 Changes to make the code compile normally on macOS. (#137)
Changes in configure to set crypt lib dynamically depending on the OS
2024-09-22 11:15:28 +02:00
welcor
e59420363a Merge branch 'master' of git@github.com:tbamud/tbamud.git 2024-09-16 22:26:44 +02:00
Thomas Arp
c838a513dd Added loop counter per while instead of global. fixes #135 (#136) 2024-09-16 22:25:29 +02:00
welcor
ed9e5e1c5a Merge branch 'master' of github.com:tbamud/tbamud 2024-06-20 22:48:59 +02:00
Dan Danese
762cb77c60 Fix a bug with the prior commit for handling triggers. It should have (#132)
continued the loop, not returned since it isn't likely to be the end of
the wld file.

Added the ability to specify multiple files on the command line. This
will load all files passed before processing into html files. This is to
fix the 'missing exits' from the output html files. The prior version
only worked on a single zone or wld file and generated incomplete
output. The record count was moved global to enable proper tracking of
the entire world. The index_boot function was modified to scan the files
first, get a record count, then start over and load the room records.

example usage: wld2html *.wld

This command will generate the entire world as one html file per room.

Fixed room number roll over. The original was using a short int which is
a 16bit int and rolls at 32k.

Fixed an issue where the html files would get negative names due to
integer rollover. It had something to do with sprintf an int using %d,
but only if you passed that to fopen. Casting the int (room number) to
a long before using sprintf with %ld fixed the issue.

Added the missing four directions from the dir_names array and defines.

Co-authored-by: Dan Danese <biouxtia@danese.us>
2024-06-20 19:56:51 +02:00
Thomas Arp
317286d051 Ignore project files on commit, and fix the automap bug showing two (#133)
descriptions
2024-06-20 19:31:20 +02:00
Dan Danese
ac711ffff8 Update wld2html.c (#131)
Triggers on elements of the room break this utility. Added code to toss them since we don't need them. Can add handling that pulls the trigger info later if desired, but too time consuming to index them before building the room for this simple tool.
2024-06-18 20:56:13 +02:00
Thomas Arp
cde4b84be1 Update FAQ.txt (#130)
Added info about generated maps for the areas on tbaMUD
2024-06-08 12:12:54 +02:00
Nick Schmoyer
5da67ddc6a Add missing lookup for flags in read_ibt (#128) 2024-03-02 23:11:28 +01:00
Roman Shapiro
b2d38522e0 Added new easy way of building TbaMUD in the Visual Studio through the CMake (#127)
* Added new experimental MSVC build way through CMake

* Small build/README.md fix
2023-11-19 04:04:39 +01:00
Serge
498b652546 fixed small bug in toggle showvnum (#125)
Thanks, @prool
2023-01-07 15:43:06 +01:00
22 changed files with 935 additions and 315 deletions

83
.gitignore vendored
View File

@@ -10,3 +10,86 @@ src/util/Makefile
src/.accepted src/.accepted
src/depend src/depend
src/util/depend src/util/depend
build/*
!build/create_solution.bat
!build/README.md
# Do not commit files from players
lib/plrfiles/A-E/*
lib/plrfiles/F-J/*
lib/plrfiles/K-O/*
lib/plrfiles/P-T/*
lib/plrfiles/U-Z/*
lib/plrfiles/ZZZ/*
lib/plrfiles/index
# but do commit the placeholders
!lib/plrfiles/A-E/00
!lib/plrfiles/F-J/00
!lib/plrfiles/K-O/00
!lib/plrfiles/P-T/00
!lib/plrfiles/U-Z/00
!lib/plrfiles/ZZZ/00
# or vars
lib/plrvars/A-E/*
lib/plrvars/F-J/*
lib/plrvars/K-O/*
lib/plrvars/P-T/*
lib/plrvars/U-Z/*
lib/plrvars/ZZZ/*
lib/plrvars/index
# except the placeholders
!lib/plrvars/A-E/00
!lib/plrvars/F-J/00
!lib/plrvars/K-O/00
!lib/plrvars/P-T/00
!lib/plrvars/U-Z/00
!lib/plrvars/ZZZ/00
# or objects
lib/plrobjs/A-E/*
lib/plrobjs/F-J/*
lib/plrobjs/K-O/*
lib/plrobjs/P-T/*
lib/plrobjs/U-Z/*
lib/plrobjs/ZZZ/*
lib/plrobjs/index
# except the placeholders
!lib/plrobjs/A-E/00
!lib/plrobjs/F-J/00
!lib/plrobjs/K-O/00
!lib/plrobjs/P-T/00
!lib/plrobjs/U-Z/00
!lib/plrobjs/ZZZ/00
# also not autogenerated config file
/lib/etc/config
# or the list of last logins
/lib/etc/last
# or mail
lib/etc/plrmail
# test object files, etc
src/test/depend
src/test/*.o
src/test/testfile
# ide etc.
.vscode
.project
.settings
.cproject
# macOS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

15
build/README.md Normal file
View File

@@ -0,0 +1,15 @@
### Overview
This guide describes how to build TbaMUD in the Visual Studio through the new experimental CMake environment.
### Prerequisites
* [Visual Studio 2022+](https://visualstudio.microsoft.com/ru/vs/)
* [CMake 3.27+](https://cmake.org/)
### Build Steps
1. Goto the folder `src` and copy `conf.h.win` to `conf.h`.
2. Goto the folder `build` and execute `create_solution.bat`.
3. Open `build/circle.sln` in Visual Studio.
4. Compile and run.

View File

@@ -0,0 +1 @@
cmake -B . -S ..\src -G "Visual Studio 17 2022"

47
configure vendored
View File

@@ -1227,18 +1227,28 @@ if eval "test \"`echo '$ac_cv_func_'crypt`\" = yes"; then
cat >> confdefs.h <<\EOF cat >> confdefs.h <<\EOF
#define CIRCLE_CRYPT 1 #define CIRCLE_CRYPT 1
EOF EOF
CRYPTLIB="-lcrypt"
echo "CRYPTLIB set to: $CRYPTLIB" 1>&6
else else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
echo "configure:1235: checking for crypt in -lcrypt" >&5 echo "configure:1235: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then OS_NAME=$(uname)
if [ "$OS_NAME" = "Darwin" ]; then
# macOS: No need for -lcrypt
CRYPTLIB=""
echo "CRYPTLIB not needed on macOS" 1>&6
else
# Other systems (Linux): Use -lcrypt
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS" LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1243 "configure" #line 1243 "configure"
#include "confdefs.h" #include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */ /* Override any gcc2 internal prototype to avoid an error. */
@@ -1250,30 +1260,29 @@ int main() {
crypt() crypt()
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:1254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:1254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes" eval "ac_cv_lib_$ac_lib_var=yes"
else else
echo "configure: failed program was:" >&5 echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5 cat conftest.$ac_ext >&5
rm -rf conftest* rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no" eval "ac_cv_lib_$ac_lib_var=no"
fi fi
rm -f conftest* rm -f conftest*
LIBS="$ac_save_LIBS" LIBS="$ac_save_LIBS"
fi
fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6 echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF cat >> confdefs.h <<\EOF
#define CIRCLE_CRYPT 1 #define CIRCLE_CRYPT 1
EOF EOF
CRYPTLIB="-lcrypt" CRYPTLIB="-lcrypt"
else echo "CRYPTLIB set to: $CRYPTLIB on Linux" 1>&6
else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
fi fi
fi
fi fi

View File

@@ -257,6 +257,9 @@ http://tbamud.com
All donated areas have been added to the latest version of tbaMUD. If you All donated areas have been added to the latest version of tbaMUD. If you
wish to donate some of your own work stop by the Builder Academy. wish to donate some of your own work stop by the Builder Academy.
https://github.com/rds1983 has generated maps of all the existing areas,
and they can be found here: https://mudmapbuilder.github.io/
2.3. I have questions about tbaMUD. Where should I go? 2.3. I have questions about tbaMUD. Where should I go?
Stop by The Builder Academy at tbamud.com 9091 or the website at: Stop by The Builder Academy at tbamud.com 9091 or the website at:

View File

@@ -10,6 +10,7 @@ to rec.games.mud.diku which originally announced CircleMUD as a publicly
available MUD source code. available MUD source code.
tbaMUD Release history: tbaMUD Release history:
Version 2025 release: January, 2025
Version 2023 release: January, 2023 Version 2023 release: January, 2023
Version 2021 release: March, 2021 Version 2021 release: March, 2021
Version 2020 release: January, 2020 Version 2020 release: January, 2020

View File

@@ -1,5 +1,5 @@
T B A M U D T B A M U D
2 0 2 3 2 0 2 5
Based on CircleMUD by Jeremy Elson and DikuMUD by Hans-Henrik Staerfeldt, Based on CircleMUD by Jeremy Elson and DikuMUD by Hans-Henrik Staerfeldt,
Katja Nyboe, Tom Madsen, Michael Seifert, and Sebastian Hammer Katja Nyboe, Tom Madsen, Michael Seifert, and Sebastian Hammer

26
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.27)
# Set the project name
project(circle)
# Global definitions
if(MSVC)
# using Visual Studio C++
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
endif()
# circle itself
file(GLOB CIRCLE_SOURCES
"*.h"
"*.c"
)
add_executable(circle ${CIRCLE_SOURCES})
if(MSVC)
target_link_libraries(circle wsock32.lib)
set_target_properties(circle PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/.."
)
endif()

View File

@@ -20,8 +20,8 @@ CFLAGS = @CFLAGS@ $(MYFLAGS) $(PROFILE)
LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@ LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@
SRCFILES := act.comm.c act.informative.c act.item.c act.movement.c act.offensive.c act.other.c act.social.c act.wizard.c aedit.c asciimap.c ban.c boards.c bsd-snprintf.c castle.c cedit.c class.c comm.c config.c constants.c db.c dg_comm.c dg_db_scripts.c dg_event.c dg_handler.c dg_misc.c dg_mobcmd.c dg_objcmd.c dg_olc.c dg_scripts.c dg_triggers.c dg_variables.c dg_wldcmd.c fight.c genmob.c genobj.c genolc.c genqst.c genshp.c genwld.c genzon.c graph.c handler.c hedit.c house.c ibt.c improved-edit.c interpreter.c limits.c lists.c magic.c mail.c medit.c mobact.c modify.c msgedit.c mud_event.c oasis.c oasis_copy.c oasis_delete.c oasis_list.c objsave.c oedit.c players.c prefedit.c protocol.c qedit.c quest.c random.c redit.c sedit.c shop.c spec_assign.c spec_procs.c spell_parser.c spells.c tedit.c utils.c weather.c zedit.c zmalloc.c SRCFILES := $(shell ls *.c | sort)
OBJFILES := act.comm.o act.informative.o act.item.o act.movement.o act.offensive.o act.other.o act.social.o act.wizard.o aedit.o asciimap.o ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o comm.o config.o constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o dg_handler.o dg_misc.o dg_mobcmd.o dg_objcmd.o dg_olc.o dg_scripts.o dg_triggers.o dg_variables.o dg_wldcmd.o fight.o genmob.o genobj.o genolc.o genqst.o genshp.o genwld.o genzon.o graph.o handler.o hedit.o house.o ibt.o improved-edit.o interpreter.o limits.o lists.o magic.o mail.o medit.o mobact.o modify.o msgedit.o mud_event.o oasis.o oasis_copy.o oasis_delete.o oasis_list.o objsave.o oedit.o players.o prefedit.o protocol.o qedit.o quest.o random.o redit.o sedit.o shop.o spec_assign.o spec_procs.o spell_parser.o spells.o tedit.o utils.o weather.o zedit.o zmalloc.o OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
default: all default: all

56
src/Makefile.macOS Normal file
View File

@@ -0,0 +1,56 @@
# tbaMUD Makefile.in - Makefile template used by 'configure'
# Clean-up provided by seqwith.
# C compiler to use
CC = gcc
# Any special flags you want to pass to the compiler
MYFLAGS = -Wall -Wno-char-subscripts -Wno-invalid-source-encoding -DMEMORY_DEBUG
#flags for profiling (see hacker.doc for more information)
PROFILE =
##############################################################################
# Do Not Modify Anything Below This Line (unless you know what you're doing) #
##############################################################################
BINDIR = ../bin
CFLAGS = -g -O0 $(MYFLAGS) $(PROFILE)
LIBS =
SRCFILES := $(shell ls *.c | sort)
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
default: all
all: .accepted
$(MAKE) $(BINDIR)/circle
$(MAKE) utils
.accepted:
@./licheck less
utils: .accepted
(cd util; $(MAKE) all)
circle:
$(MAKE) $(BINDIR)/circle
$(BINDIR)/circle : $(OBJFILES)
$(CC) -o $(BINDIR)/circle $(PROFILE) $(OBJFILES) $(LIBS)
$%.o: %.c
$(CC) $< $(CFLAGS) -c -o $@
clean:
rm -f *.o depend
# Dependencies for the object files (automagically generated with
# gcc -MM)
depend:
$(CC) -MM *.c > depend
-include depend

View File

@@ -519,17 +519,19 @@ void look_at_room(struct char_data *ch, int ignore_brief)
send_to_char(ch, "]"); send_to_char(ch, "]");
} }
} }
else { else
send_to_char(ch, "%s", world[IN_ROOM(ch)].name); send_to_char(ch, "%s", world[IN_ROOM(ch)].name);
send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM)); send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief || if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) { ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch)) if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room); str_and_map(world[target_room].description, ch, target_room);
else
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
} }
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
/*autoexits */ /*autoexits */
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT)) if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
@@ -538,7 +540,6 @@ void look_at_room(struct char_data *ch, int ignore_brief)
/*now list characters &objects */ /*now list characters &objects */
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE); list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE);
list_char_to_char(world[IN_ROOM(ch)].people, ch); list_char_to_char(world[IN_ROOM(ch)].people, ch);
}
} }
static void look_in_direction(struct char_data *ch, int dir) static void look_in_direction(struct char_data *ch, int dir)
@@ -604,7 +605,8 @@ static void look_in_obj(struct char_data *ch, char *arg)
} }
else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0)) else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0))
send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */ send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */
else { else
{
char buf2[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH];
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0); amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2)); sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));

View File

@@ -566,10 +566,10 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
aedit_disp_menu(d); aedit_disp_menu(d);
return; return;
} }
if (OLC_ACTION(d)->sort_as) { if (OLC_ACTION(d)->sort_as)
free(OLC_ACTION(d)->sort_as); free(OLC_ACTION(d)->sort_as);
OLC_ACTION(d)->sort_as = strdup(arg); OLC_ACTION(d)->sort_as = strdup(arg);
}
break; break;
case AEDIT_MIN_CHAR_POS: case AEDIT_MIN_CHAR_POS:

View File

@@ -1596,7 +1596,7 @@ static int process_output(struct descriptor_data *t)
result = write_to_descriptor(t->descriptor, osb); result = write_to_descriptor(t->descriptor, osb);
if (result < 0) { /* Oops, fatal error. Bye! */ if (result < 0) { /* Oops, fatal error. Bye! */
close_socket(t); // close_socket(t); // close_socket is called after return of negative result
return (-1); return (-1);
} else if (result == 0) /* Socket buffer full. Try later. */ } else if (result == 0) /* Socket buffer full. Try later. */
return (0); return (0);

367
src/conf.h.macOS Normal file
View File

@@ -0,0 +1,367 @@
#ifndef _CONF_H_
#define _CONF_H_
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1
/* Define if you have the vprintf function. */
#define HAVE_VPRINTF 1
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef pid_t */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define to `unsigned' if <sys/types.h> doesn't define. */
/* #undef size_t */
/* Define if you have the ANSI C header files. */
/* #undef STDC_HEADERS */
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define if we're compiling CircleMUD under any type of UNIX system. */
#define CIRCLE_UNIX 1
/* Machine-specific dependencies for running on modern macOS systems 10.13+ (High Sierra)
* Updated by Victor Augusto Borges Dias de Almeida (aka Stoneheart), 26 June 2024.
*
* Tested on:
* - macOS 10.13: High Sierra - September 25, 2017 (Latest: 10.13.6)
* - macOS 10.14: Mojave - September 24, 2018 (Latest: 10.14.6)
* - macOS 10.15: Catalina - October 7, 2019 (Latest: 10.15.7)
* - macOS 11: Big Sur - November 12, 2020 (Latest: 11.7.10)
* - macOS 12: Monterey - October 25, 2021 (Latest: 12.7)
* - macOS 13: Ventura - November 7, 2022 (Latest: 13.7)
* - macOS 14: Sonoma - November 7, 2023 (Latest: 14.3)
*
* This file works on Apple Silicon Chips (M1, M2, M3) without futher configurations. */
#if defined(__APPLE__) && defined(__MACH__)
#define CIRCLE_MAC_OS 1
#endif
/* Define if the system is capable of using crypt() to encrypt. */
#define CIRCLE_CRYPT 1
/* Define if we don't have proper support for the system's crypt(). */
/* #undef HAVE_UNSAFE_CRYPT */
/* Define is the system has struct in_addr. */
#define HAVE_STRUCT_IN_ADDR 1
/* Define to `int' if <sys/socket.h> doesn't define. */
/* #undef socklen_t */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef ssize_t */
/* Define if you have the gettimeofday function. */
#define HAVE_GETTIMEOFDAY 1
/* Define if you have the inet_addr function. */
#define HAVE_INET_ADDR 1
/* Define if you have the inet_aton function. */
#define HAVE_INET_ATON 1
/* Define if you have the select function. */
#define HAVE_SELECT 1
/* Define if you have the snprintf function. */
#define HAVE_SNPRINTF 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1
/* Define if you have the strdup function. */
#define HAVE_STRDUP 1
/* Define if you have the strerror function. */
#define HAVE_STRERROR 1
/* Define if you have the stricmp function. */
/* #undef HAVE_STRICMP */
/* Define if you have the strlcpy function. */
#ifndef CIRCLE_MAC_OS
#define HAVE_STRLCPY 1
#else
#define HAVE_STRLCPY 0
#endif
/* Define if you have the strncasecmp function. */
#define HAVE_STRNCASECMP 1
/* Define if you have the strnicmp function. */
/* #undef HAVE_STRNICMP */
/* Define if you have the strstr function. */
#define HAVE_STRSTR 1
/* Define if you have the vsnprintf function. */
#define HAVE_VSNPRINTF 1
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define if you have the <arpa/telnet.h> header file. */
#define HAVE_ARPA_TELNET_H 1
/* Define if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define if you have the <crypt.h> header file. */
/* #undef HAVE_CRYPT_H */
#ifdef CIRCLE_MAC_OS
#define HAVE_CRYPT_H 1
#endif
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if you have the <mcheck.h> header file. */
/* #undef HAVE_MCHECK_H */
#ifdef CIRCLE_MAC_OS
#define HAVE_MCHECK_H 1
#endif
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the <net/errno.h> header file. */
/* #undef HAVE_NET_ERRNO_H */
/* Define if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <sys/fcntl.h> header file. */
#define HAVE_SYS_FCNTL_H 1
/* Define if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the malloc library (-lmalloc). */
/* #undef HAVE_LIBMALLOC */
/* Check for a prototype to accept. */
/* #undef NEED_ACCEPT_PROTO */
#ifndef CIRCLE_MAC_OS
/* Check for a prototype to atoi. */
#define NEED_ATOI_PROTO
/* Check for a prototype to atol. */
#define NEED_ATOL_PROTO
#endif
/* Check for a prototype to bind. */
/* #undef NEED_BIND_PROTO */
/* Check for a prototype to bzero. */
/* #undef NEED_BZERO_PROTO */
/* Check for a prototype to chdir. */
/* #undef NEED_CHDIR_PROTO */
/* Check for a prototype to close. */
/* #undef NEED_CLOSE_PROTO */
/* Check for a prototype to crypt. */
/* #undef NEED_CRYPT_PROTO */
/* Check for a prototype to fclose. */
/* #undef NEED_FCLOSE_PROTO */
/* Check for a prototype to fcntl. */
/* #undef NEED_FCNTL_PROTO */
/* Check for a prototype to fflush. */
/* #undef NEED_FFLUSH_PROTO */
/* Check for a prototype to fprintf. */
/* #undef NEED_FPRINTF_PROTO */
/* Check for a prototype to fputc. */
/* #undef NEED_FPUTC_PROTO */
/* Check for a prototype to fputs. */
/* #undef NEED_FPUTS_PROTO */
/* Check for a prototype to fread. */
/* #undef NEED_FREAD_PROTO */
/* Check for a prototype to fscanf. */
/* #undef NEED_FSCANF_PROTO */
/* Check for a prototype to fseek. */
/* #undef NEED_FSEEK_PROTO */
/* Check for a prototype to fwrite. */
/* #undef NEED_FWRITE_PROTO */
/* Check for a prototype to getpeername. */
/* #undef NEED_GETPEERNAME_PROTO */
/* Check for a prototype to getpid. */
/* #undef NEED_GETPID_PROTO */
/* Check for a prototype to getrlimit. */
/* #undef NEED_GETRLIMIT_PROTO */
/* Check for a prototype to getsockname. */
/* #undef NEED_GETSOCKNAME_PROTO */
/* Check for a prototype to gettimeofday. */
/* #undef NEED_GETTIMEOFDAY_PROTO */
/* Check for a prototype to htonl. */
/* #undef NEED_HTONL_PROTO */
/* Check for a prototype to htons. */
/* #undef NEED_HTONS_PROTO */
/* Check for a prototype to inet_addr. */
/* #undef NEED_INET_ADDR_PROTO */
/* Check for a prototype to inet_aton. */
/* #undef NEED_INET_ATON_PROTO */
/* Check for a prototype to inet_ntoa. */
/* #undef NEED_INET_NTOA_PROTO */
/* Check for a prototype to listen. */
/* #undef NEED_LISTEN_PROTO */
/* Check for a prototype to ntohl. */
/* #undef NEED_NTOHL_PROTO */
/* Check for a prototype to perror. */
/* #undef NEED_PERROR_PROTO */
/* Check for a prototype to printf. */
/* #undef NEED_PRINTF_PROTO */
/* Check for a prototype to qsort. */
#ifndef CIRCLE_MAC_OS
#define NEED_QSORT_PROTO
#endif
/* Check for a prototype to read. */
/* #undef NEED_READ_PROTO */
/* Check for a prototype to remove. */
/* #undef NEED_REMOVE_PROTO */
/* Check for a prototype to rewind. */
/* #undef NEED_REWIND_PROTO */
/* Check for a prototype to select. */
/* #undef NEED_SELECT_PROTO */
/* Check for a prototype to setitimer. */
/* #undef NEED_SETITIMER_PROTO */
/* Check for a prototype to setrlimit. */
/* #undef NEED_SETRLIMIT_PROTO */
/* Check for a prototype to setsockopt. */
/* #undef NEED_SETSOCKOPT_PROTO */
/* Check for a prototype to snprintf. */
/* #undef NEED_SNPRINTF_PROTO */
/* Check for a prototype to socket. */
/* #undef NEED_SOCKET_PROTO */
/* Check for a prototype to sprintf. */
/* #undef NEED_SPRINTF_PROTO */
/* Check for a prototype to sscanf. */
/* #undef NEED_SSCANF_PROTO */
/* Check for a prototype to strcasecmp. */
/* #undef NEED_STRCASECMP_PROTO */
/* Check for a prototype to strdup. */
/* #undef NEED_STRDUP_PROTO */
/* Check for a prototype to strerror. */
/* #undef NEED_STRERROR_PROTO */
/* Check for a prototype to stricmp. */
#define NEED_STRICMP_PROTO
/* Check for a prototype to strlcpy. */
/* #undef NEED_STRLCPY_PROTO */
/* Check for a prototype to strncasecmp. */
/* #undef NEED_STRNCASECMP_PROTO */
/* Check for a prototype to strnicmp. */
#define NEED_STRNICMP_PROTO
/* Check for a prototype to system. */
#ifndef CIRCLE_MAC_OS
#define NEED_SYSTEM_PROTO
#endif
/* Check for a prototype to time. */
/* #undef NEED_TIME_PROTO */
/* Check for a prototype to unlink. */
/* #undef NEED_UNLINK_PROTO */
/* Check for a prototype to vsnprintf. */
/* #undef NEED_VSNPRINTF_PROTO */
/* Check for a prototype to write. */
/* #undef NEED_WRITE_PROTO */
#endif /* _CONF_H_ */

View File

@@ -24,7 +24,7 @@
* @todo cpp_extern isn't needed here (or anywhere) as the extern reserved word * @todo cpp_extern isn't needed here (or anywhere) as the extern reserved word
* works correctly with C compilers (at least in my Experience) * works correctly with C compilers (at least in my Experience)
* Jeremy Osborne 1/28/2008 */ * Jeremy Osborne 1/28/2008 */
cpp_extern const char *tbamud_version = "tbaMUD 2023"; cpp_extern const char *tbamud_version = "tbaMUD 2025";
/* strings corresponding to ordinals/bitvectors in structs.h */ /* strings corresponding to ordinals/bitvectors in structs.h */
/* (Note: strings for class definitions in class.c instead of here) */ /* (Note: strings for class definitions in class.c instead of here) */

View File

@@ -1091,70 +1091,85 @@ int format_script(struct descriptor_data *d)
char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE]; char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE];
char *sc; char *sc;
size_t len = 0, nlen = 0, llen = 0; size_t len = 0, nlen = 0, llen = 0;
int indent = 0, indent_next = FALSE, found_case = FALSE, i, line_num = 0, ret; int indent = 0, indent_next = FALSE, line_num = 0, ret, i; // Declare i here
int block_stack[READ_SIZE]; // Stack to track block types
int stack_top = -1; // Initialize stack as empty
int switch_indent[READ_SIZE]; // Array to track switch indent levels
int switch_top = -1; // Index for switch_indent array
int case_indent = 0; // Track indent for case blocks
int in_switch = 0; // Flag to indicate if we're inside a switch block
if (!d->str || !*d->str) if (!d->str || !*d->str)
return FALSE; return FALSE;
sc = strdup(*d->str); /* we work on a copy, because of strtok() */ sc = strdup(*d->str); // Work on a copy
t = strtok(sc, "\n\r"); t = strtok(sc, "\n\r");
*nsc = '\0'; *nsc = '\0';
while (t) { while (t) {
line_num++; line_num++;
skip_spaces(&t); skip_spaces(&t);
if (!strn_cmp(t, "if ", 3) ||
!strn_cmp(t, "switch ", 7)) { if (!strn_cmp(t, "switch ", 7)) {
indent_next = TRUE; indent_next = TRUE;
} else if (!strn_cmp(t, "while ", 6)) { stack_top++;
found_case = TRUE; /* so you can 'break' a loop without complains */ block_stack[stack_top] = 's'; // 's' for switch
switch_top++;
switch_indent[switch_top] = indent; // Save current indent level for switch
in_switch++; // We're entering a switch block
} else if (!strn_cmp(t, "case", 4) || !strn_cmp(t, "default", 7)) {
if (in_switch > 0) { // If we're inside a switch
indent = switch_indent[switch_top] + 1; // Indent cases one level under switch
indent_next = TRUE; // Indent the next line after case
case_indent = indent; // Save indent for case block
}
} else if (!strn_cmp(t, "if ", 3) || !strn_cmp(t, "while ", 6)) {
indent_next = TRUE; indent_next = TRUE;
} else if (!strn_cmp(t, "end", 3) || stack_top++;
!strn_cmp(t, "done", 4)) { block_stack[stack_top] = 'l'; // 'l' for loop or conditional
if (!indent) { } else if (!strn_cmp(t, "end", 3) || !strn_cmp(t, "done", 4)) {
if (stack_top < 0) {
write_to_output(d, "Unmatched 'end' or 'done' (line %d)!\r\n", line_num); write_to_output(d, "Unmatched 'end' or 'done' (line %d)!\r\n", line_num);
free(sc); free(sc);
return FALSE; return FALSE;
} }
indent--; if (block_stack[stack_top] == 's') {
indent_next = FALSE; indent = switch_indent[switch_top]; // Reset to the exact indent level where switch was declared
switch_top--; // Decrease switch stack if ending a switch
case_indent = 0; // Reset case indent since we're leaving the switch
in_switch--; // We're leaving a switch block
} else {
indent--; // For other blocks like while
}
stack_top--;
indent_next = FALSE; // Reset for next line
} else if (!strn_cmp(t, "else", 4)) { } else if (!strn_cmp(t, "else", 4)) {
if (!indent) { if (stack_top < 0 || block_stack[stack_top] != 'l') {
write_to_output(d, "Unmatched 'else' (line %d)!\r\n", line_num); write_to_output(d, "Unmatched 'else' (line %d)!\r\n", line_num);
free(sc); free(sc);
return FALSE; return FALSE;
} }
indent--; indent--; // Reduce indent for else, then increment for next statement
indent_next = TRUE; indent_next = TRUE;
} else if (!strn_cmp(t, "case", 4) ||
!strn_cmp(t, "default", 7)) {
if (!indent) {
write_to_output(d, "Case/default outside switch (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
if (!found_case) /* so we don't indent multiple case statements without a break */
indent_next = TRUE;
found_case = TRUE;
} else if (!strn_cmp(t, "break", 5)) { } else if (!strn_cmp(t, "break", 5)) {
if (!found_case || !indent ) { if (stack_top < 0 || (block_stack[stack_top] != 's' && block_stack[stack_top] != 'l')) {
write_to_output(d, "Break not in case (line %d)!\r\n", line_num); write_to_output(d, "Break not in case or loop (line %d)!\r\n", line_num);
free(sc); free(sc);
return FALSE; return FALSE;
} }
found_case = FALSE; indent = case_indent + 1; // Indent break one level deeper than case
indent--; indent_next = FALSE; // Ensure no automatic increase for next line after break
} }
*line = '\0'; *line = '\0';
for (nlen = 0, i = 0;i<indent;i++) { for (nlen = 0, i = 0; i < indent; i++) {
strncat(line, " ", sizeof(line) - strlen(line) - 1); strncat(line, " ", sizeof(line) - strlen(line) - 1);
nlen += 2; nlen += 2;
} }
ret = snprintf(line + nlen, sizeof(line) - nlen, "%s\r\n", t); ret = snprintf(line + nlen, sizeof(line) - nlen, "%s\r\n", t);
llen = (size_t)ret; llen = (size_t)ret;
if (ret < 0 || llen + nlen + len > d->max_str - 1 ) { if (ret < 0 || llen + nlen + len > d->max_str - 1) {
write_to_output(d, "String too long, formatting aborted\r\n"); write_to_output(d, "String too long, formatting aborted\r\n");
free(sc); free(sc);
return FALSE; return FALSE;
@@ -1169,8 +1184,8 @@ int format_script(struct descriptor_data *d)
t = strtok(NULL, "\n\r"); t = strtok(NULL, "\n\r");
} }
if (indent) if (stack_top >= 0)
write_to_output(d, "Unmatched if, while or switch ignored.\r\n"); write_to_output(d, "Unmatched block statements ignored.\r\n");
free(*d->str); free(*d->str);
*d->str = strdup(nsc); *d->str = strdup(nsc);

View File

@@ -2486,7 +2486,6 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
char cmd[MAX_INPUT_LENGTH], *p; char cmd[MAX_INPUT_LENGTH], *p;
struct script_data *sc = 0; struct script_data *sc = 0;
struct cmdlist_element *temp; struct cmdlist_element *temp;
unsigned long loops = 0;
void *go = NULL; void *go = NULL;
void obj_command_interpreter(obj_data *obj, char *argument); void obj_command_interpreter(obj_data *obj, char *argument);
@@ -2578,8 +2577,8 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
if (process_if(p + 6, go, sc, trig, type)) { if (process_if(p + 6, go, sc, trig, type)) {
temp->original = cl; temp->original = cl;
} else { } else {
cl->loops = 0;
cl = temp; cl = temp;
loops = 0;
} }
} else if (!strn_cmp("switch ", p, 7)) { } else if (!strn_cmp("switch ", p, 7)) {
cl = find_case(trig, cl, go, sc, type, p + 7); cl = find_case(trig, cl, go, sc, type, p + 7);
@@ -2599,9 +2598,10 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
if (cl->original && process_if(orig_cmd + 6, go, sc, trig, if (cl->original && process_if(orig_cmd + 6, go, sc, trig,
type)) { type)) {
cl = cl->original; cl = cl->original;
loops++; cl->loops++;
GET_TRIG_LOOPS(trig)++; GET_TRIG_LOOPS(trig)++;
if (loops == 30) { if (cl->loops == 30) {
cl->loops = 0;
process_wait(go, trig, type, "wait 1", cl); process_wait(go, trig, type, "wait 1", cl);
depth--; depth--;
return ret_val; return ret_val;

View File

@@ -135,6 +135,7 @@ struct cmdlist_element {
char *cmd; /* one line of a trigger */ char *cmd; /* one line of a trigger */
struct cmdlist_element *original; struct cmdlist_element *original;
struct cmdlist_element *next; struct cmdlist_element *next;
int loops; /* for counting number of runs in a while loop */
}; };
struct trig_var_data { struct trig_var_data {

View File

@@ -177,6 +177,13 @@ static IBT_DATA *read_ibt( char *filename, FILE *fp )
} }
break; break;
case 'F':
if (!str_cmp(word, "Flags")) {
fMatch = TRUE;
fread_flags(fp, ibtData->flags, 4);
}
break;
case 'I': case 'I':
TXT_KEY("IdNum", id_num, fread_line(fp)); TXT_KEY("IdNum", id_num, fread_line(fp));
break; break;

View File

@@ -13,6 +13,11 @@
#include <sys/types.h> #include <sys/types.h>
#include "protocol.h" #include "protocol.h"
#ifdef _MSC_VER
#include "telnet.h"
#define alloca _alloca
#endif
/****************************************************************************** /******************************************************************************
The following section is for Diku/Merc derivatives. Replace as needed. The following section is for Diku/Merc derivatives. Replace as needed.
******************************************************************************/ ******************************************************************************/

View File

@@ -63,6 +63,24 @@
/* Do not change anything below this line. */ /* Do not change anything below this line. */
#if defined(__APPLE__) && defined(__MACH__)
/* Machine-specific dependencies for running on modern macOS systems 10.13+ (High Sierra)
* Updated by Victor Augusto Borges Dias de Almeida (aka Stoneheart), 26 June 2024.
*
* Tested on:
* - macOS 10.13: High Sierra (Lobo) - September 25, 2017 (Latest: 10.13.6)
* - macOS 10.14: Mojave (Liberty) - September 24, 2018 (Latest: 10.14.6)
* - macOS 10.15: Catalina (Jazz) - October 7, 2019 (Latest: 10.15.7)
* - macOS 11: Big Sur (GoldenGate) - November 12, 2020 (Latest: 11.7.10)
* - macOS 12: Monterey (Star) - October 25, 2021 (Latest: 12.7)
* - macOS 13: Ventura (Rome) - November 7, 2022 (Latest: 13.7)
* - macOS 14: Sonoma (Sunburst) - November 7, 2023 (Latest: 14.3)
*
* This file works on Apple Silicon Chips (M1, M2, M3) without futher configurations.
*/
#define CIRCLE_MAC_OS 1
#endif
/* Set up various machine-specific things based on the values determined from /* Set up various machine-specific things based on the values determined from
* configure and conf.h. */ * configure and conf.h. */
@@ -78,7 +96,7 @@
#include <strings.h> #include <strings.h>
#endif #endif
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) #if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) || defined(CIRCLE_MAC_OS))
#include <stdlib.h> #include <stdlib.h>
#else /* No standard headers. */ #else /* No standard headers. */
@@ -88,9 +106,8 @@
#endif #endif
extern char *malloc(), *calloc(), *realloc(); extern char *malloc(), *calloc(), *realloc();
extern void free (); extern void free();
extern void abort(), exit();
extern void abort (), exit ();
#endif /* Standard headers. */ #endif /* Standard headers. */
@@ -150,9 +167,11 @@ extern void abort (), exit ();
#include <sys/errno.h> #include <sys/errno.h>
#endif #endif
#ifndef CIRCLE_MAC_OS
#ifdef HAVE_CRYPT_H #ifdef HAVE_CRYPT_H
#include <crypt.h> #include <crypt.h>
#endif #endif
#endif
#ifdef TIME_WITH_SYS_TIME #ifdef TIME_WITH_SYS_TIME
# include <sys/time.h> # include <sys/time.h>
@@ -434,9 +453,11 @@ struct in_addr {
char *strerror(int errnum); char *strerror(int errnum);
#endif #endif
#ifndef CIRCLE_MAC_OS
#ifdef NEED_STRLCPY_PROTO #ifdef NEED_STRLCPY_PROTO
size_t strlcpy(char *dest, const char *src, size_t copylen); size_t strlcpy(char *dest, const char *src, size_t copylen);
#endif #endif
#endif
#ifdef NEED_SYSTEM_PROTO #ifdef NEED_SYSTEM_PROTO
int system(const char *string); int system(const char *string);

View File

@@ -12,7 +12,6 @@
#include "conf.h" #include "conf.h"
#include "sysdep.h" #include "sysdep.h"
#define NOWHERE -1 /* nil reference for room-database */ #define NOWHERE -1 /* nil reference for room-database */
/* The cardinal directions: used as index to room_data.dir_option[] */ /* The cardinal directions: used as index to room_data.dir_option[] */
@@ -22,14 +21,17 @@
#define WEST 3 #define WEST 3
#define UP 4 #define UP 4
#define DOWN 5 #define DOWN 5
#define NORTHWEST 6
#define NORTHEAST 7
#define SOUTHEAST 8
#define SOUTHWEST 9
#define NUM_OF_DIRS 6 #define NUM_OF_DIRS 10
#define CREATE(result, type, number) do {\ #define CREATE(result, type, number) do {\
if (!((result) = (type *) calloc ((number), sizeof(type))))\ if (!((result) = (type *) calloc ((number), sizeof(type))))\
{ perror("malloc failure"); abort(); } } while(0) { perror("malloc failure"); abort(); } } while(0)
/* Exit info: used in room_data.dir_option.exit_info */ /* Exit info: used in room_data.dir_option.exit_info */
#define EX_ISDOOR (1 << 0) /* Exit is a door */ #define EX_ISDOOR (1 << 0) /* Exit is a door */
#define EX_CLOSED (1 << 1) /* The door is closed */ #define EX_CLOSED (1 << 1) /* The door is closed */
@@ -45,7 +47,7 @@ typedef unsigned short int ush_int;
typedef char bool; typedef char bool;
typedef char byte; typedef char byte;
typedef sh_int room_num; typedef int room_num;
typedef sh_int obj_num; typedef sh_int obj_num;
@@ -133,13 +135,14 @@ struct room_data {
struct room_data *world = NULL; /* array of rooms */ struct room_data *world = NULL; /* array of rooms */
int top_of_world = 0; /* ref to top element of world */ int top_of_world = 0; /* ref to top element of world */
int rec_count = 0;
/* local functions */ /* local functions */
char *fread_string(FILE * fl, char *error); char *fread_string(FILE * fl, char *error);
void setup_dir(FILE * fl, int room, int dir); void setup_dir(FILE * fl, int room, int dir);
void index_boot(char *name); void index_boot(int cnt, char **name);
void discrete_load(FILE * fl); void discrete_load(FILE * fl);
void parse_room(FILE * fl, int virtual_nr); void parse_room(FILE * fl, int virtual_nr);
void parse_mobile(FILE * mob_f, int nr); void parse_mobile(FILE * mob_f, int nr);
@@ -150,7 +153,7 @@ void write_output(void);
char *dir_names[] = char *dir_names[] =
{"North", "East", "South", "West", "Up", "Down"}; {"North", "East", "South", "West", "Up", "Down","North West","North East","South East","South West"};
/************************************************************************* /*************************************************************************
@@ -160,14 +163,12 @@ char *dir_names[] =
/* body of the booting system */ /* body of the booting system */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 2) { if (argc < 2) {
fprintf(stderr, "Usage: %s <world-file-name>\n", argv[0]); fprintf(stderr, "Usage: %s <world-file-name(s)>\n", argv[0]);
exit(1); exit(1);
} }
index_boot(argv[1]);
log("Renumbering rooms."); index_boot(argc,argv);
renum_world();
log("Writing output."); log("Writing output.");
write_output(); write_output();
@@ -176,6 +177,21 @@ int main(int argc, char **argv)
return (0); return (0);
} }
/* Since the world is loaded into memory by index
* and not room number, we need to search through
* all rooms and return the correct one. This is
* used to generate door information (ie: the name)
*/
struct room_data* findRoom(int nr)
{
int i;
for (i=0;i<rec_count;i++)
if (world[i].number==nr)
return &world[i];
return NULL;
}
void write_output(void) void write_output(void)
{ {
@@ -184,11 +200,22 @@ void write_output(void)
char buf[128]; char buf[128];
register int door, found; register int door, found;
for (i = 0; i <= top_of_world; i++) { for (i=0;i<rec_count;i++) {
//print the record number, but no linefeed.
fprintf(stderr, "Record: %d ",i);
if (world[i].name == NULL) {
//linefeed the prior record since we're skipping this one.
log("");
//the name is blank, which means, most likely, the record is bad as well.
continue;
}
sprintf(buf, "Writing %d.html", world[i].number); sprintf(buf, "Writing %d.html", world[i].number);
log(buf); log(buf);
sprintf(buf, "%d.html", world[i].number); //for some reason, if you use %d with sprintf it rolls over like its 16bit,
//but only if you use the buffer with fopen.
//using %ld and casting to long solves this in case someone really wants
//to use negative room numbers.
sprintf(buf, "%ld.html",(long)world[i].number);
if (!(fl = fopen(buf, "w"))) { if (!(fl = fopen(buf, "w"))) {
perror("opening output file"); perror("opening output file");
exit(1); exit(1);
@@ -205,10 +232,14 @@ void write_output(void)
if (world[i].dir_option[door] && if (world[i].dir_option[door] &&
world[i].dir_option[door]->to_room != NOWHERE) { world[i].dir_option[door]->to_room != NOWHERE) {
found = 1; found = 1;
//this call gets a pointer to the room referenced by the to_room for the door.
//This fixes a lot of issues introduced with the whole 'renumbering rooms' call
//and the binary search that didn't work well.
struct room_data* to_room = findRoom(world[i].dir_option[door]->to_room);
fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n", fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n",
world[world[i].dir_option[door]->to_room].number, to_room->number,
dir_names[door], dir_names[door],
world[world[i].dir_option[door]->to_room].name); to_room->name);
} }
if (!found) if (!found)
fprintf(fl, "None!"); fprintf(fl, "None!");
@@ -231,19 +262,35 @@ int count_hash_records(FILE * fl)
void index_boot(char *name) void index_boot(int cnt, char **names)
{ {
FILE *db_file; FILE *db_file;
int rec_count = 0;
if (!(db_file = fopen(name, "r"))) { //throw first entry away as that is the executable.
for (int i=1;i<cnt;i++) {
if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file"); perror("error opening world file");
exit(1); exit(1);
} }
rec_count = count_hash_records(db_file); //have to loop through files twice.
//once to get total record count
//second time to load them
rec_count += count_hash_records(db_file);
fclose(db_file);
}
sprintf(buf,"Total records: %d\n",rec_count);
log(buf);
//now that we know how many records in total
//we can create the memory structure
CREATE(world, struct room_data, rec_count); CREATE(world, struct room_data, rec_count);
rewind(db_file); //now loop through files and load them
for (int i=1;i<cnt;i++) {
if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file");
exit(1);
}
discrete_load(db_file); discrete_load(db_file);
}
} }
@@ -257,6 +304,9 @@ void discrete_load(FILE * fl)
fprintf(stderr, "Format error after room #%d\n", nr); fprintf(stderr, "Format error after room #%d\n", nr);
exit(1); exit(1);
} }
if (*line == 'T') //Toss triggers. THey currently break this util.
continue;
if (*line == '$') if (*line == '$')
return; return;
@@ -394,22 +444,6 @@ void setup_dir(FILE * fl, int room, int dir)
} }
/* resolve all vnums into rnums in the world */
void renum_world(void)
{
register int room, door;
for (room = 0; room <= top_of_world; room++)
for (door = 0; door < NUM_OF_DIRS; door++)
if (world[room].dir_option[door])
if (world[room].dir_option[door]->to_room != NOWHERE)
world[room].dir_option[door]->to_room =
real_room(world[room].dir_option[door]->to_room,
world[room].number);
}
/************************************************************************* /*************************************************************************
* procedures for resetting, both play-time and boot-time * * procedures for resetting, both play-time and boot-time *
*********************************************************************** */ *********************************************************************** */
@@ -464,32 +498,6 @@ char *fread_string(FILE * fl, char *error)
/* returns the real number of the room with given virtual number */
int real_room(int virtual, int reference)
{
int bot, top, mid;
bot = 0;
top = top_of_world;
/* perform binary search on world-table */
for (;;) {
mid = (bot + top) / 2;
if ((world + mid)->number == virtual)
return (mid);
if (bot >= top) {
fprintf(stderr, "Room %d does not exist in database (referenced in room %d)\n", virtual, reference);
return (-1);
}
if ((world + mid)->number > virtual)
top = mid - 1;
else
bot = mid + 1;
}
}
/* get_line reads the next non-blank line off of the input stream. /* get_line reads the next non-blank line off of the input stream.
* The newline character is removed from the input. Lines which begin * The newline character is removed from the input. Lines which begin
* with '*' are considered to be comments. * with '*' are considered to be comments.