mirror of
https://github.com/brazilofmux/tinymux
synced 2026-08-13 00:23:11 -04:00
The flip: FUNCTION/XFUNCTION/FUN::fun/delim_check and the module interfaces take `const UTF8 * const fargs[]`. Double-const is load-bearing: C++ qualification conversion needs const at both pointer levels, so builder-side `UTF8 *[]` arrays convert implicitly — the evaluator, the JIT marshaller, and every owner site need zero casts, and slot reassignment inside bodies becomes a compile error for free. The conversions: the flip landed first so the compiler enumerated every violation; this commit is that inventory worked to zero — ~250 sites across funceval, funceval2, functions, funmath, help, mail, session, powers, levels, predicates, conf, walkdb, stringutil, timeutil/ date_scan (regenerated, one-line diff), exp3, and mux_main, each classified per docs/campaign-2136-const-fargs.md's four recipes. New idioms (functions.h): trim_space_sep_n() — non-destructive trim for (pointer, length) consumers, so trim-then-scan sites need no copy at all; FargVec — the argv counterpart of FargCopy for CS_ARGV handlers. countwords() and DecodeListOfIntegers() rewritten non-destructive. The flip deleted more than it added: #2157's fun_munge list1 copy, the engine_com help-topic copy, fun_index's in-place NUL write, and five const_casts (process_sex x4, sha1_helper). const_cast budget: zero added. Trap recorded in the brief: an old-signature definition doesn't fail the build — it becomes a C++ overload, and the new-signature symbol stays undefined until dlopen(RTLD_NOW). delim_check, the conn_bridge bridges, the dbt_spike stub, and exp3::Call were all silently shadowed; muxscript was the only host that noticed, because netmux's own net.cpp resolved the flat-namespace lookup. After any signature flip, grep the old spelling. Verified: make test EXPECT_CONFIG="jit=yes" (35 passed / 0 failed) and make test-scenario, including the new tests/scenario/sidefx_fargs.py that live-probes the class-3 wrappers smoke never touches (pemit/ trigger/link/tel/wipe/destroy). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
262 lines
8.5 KiB
C++
262 lines
8.5 KiB
C++
/*! \file comsys.h
|
|
* \brief Channel Communication System.
|
|
*
|
|
*/
|
|
|
|
#ifndef COMSYS_H
|
|
#define COMSYS_H
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#ifndef NOTHING
|
|
#define NOTHING (-1)
|
|
#endif
|
|
|
|
//! \def MAX_USERS_PER_CHANNEL
|
|
// Maximum Users Per Channel
|
|
#define MAX_USERS_PER_CHANNEL 1000000
|
|
|
|
//! \def MAX_CHANNEL_LEN
|
|
// Maximum length for channel names
|
|
#define MAX_CHANNEL_LEN 50
|
|
|
|
//! \def MAX_HEADER_LEN
|
|
// Maximum length for channel headers (display names)
|
|
#define MAX_HEADER_LEN 100
|
|
|
|
//! \def MAX_TITLE_LEN
|
|
// Maximum length for Player titles for channels
|
|
#define MAX_TITLE_LEN 200
|
|
|
|
//! \def MAX_ALIAS_LEN
|
|
// Maximum length for an alias to a channel
|
|
#define MAX_ALIAS_LEN 15
|
|
|
|
//! \def MAX_COST
|
|
// Maximum cost to use for a channel
|
|
#define MAX_COST 32767
|
|
|
|
//! \struct com_alias
|
|
// Per-player alias entry — pairs an alias string with its channel name.
|
|
struct com_alias
|
|
{
|
|
std::string alias;
|
|
std::string channel;
|
|
};
|
|
|
|
//! \struct comuser
|
|
// Comsys user data
|
|
struct comuser
|
|
{
|
|
//! dbref of the user
|
|
dbref who;
|
|
//! Is the user on the channel
|
|
bool bUserIsOn;
|
|
//! Per channel display name
|
|
std::string title;
|
|
//! Status of the title
|
|
bool ComTitleStatus;
|
|
//! Whether join/leave messages are suppressed for this user
|
|
bool bGagJoinLeave;
|
|
//! Whether the player is currently connected to the MUD
|
|
bool bConnected;
|
|
|
|
comuser() : who(NOTHING), bUserIsOn(false),
|
|
ComTitleStatus(true), bGagJoinLeave(false), bConnected(false) {}
|
|
};
|
|
|
|
//! \struct channel
|
|
// Channel data for Comsys
|
|
struct channel
|
|
{
|
|
//! Name of the Channel
|
|
UTF8 name[MAX_CHANNEL_LEN+1];
|
|
//! Header / Display Name of the channel
|
|
UTF8 header[MAX_HEADER_LEN+1];
|
|
//! Flag data for channel
|
|
int type;
|
|
int temp1;
|
|
int temp2;
|
|
//! Cost for channel usage
|
|
int charge;
|
|
//! Person to charge for usage
|
|
dbref charge_who;
|
|
int amount_col;
|
|
//! Channel object if set
|
|
dbref chan_obj;
|
|
//! Users on the channel, keyed by dbref
|
|
std::map<dbref, comuser> users;
|
|
//! Number of messages sent on the channel
|
|
int num_messages;
|
|
|
|
channel() : type(0), temp1(0), temp2(0), charge(0),
|
|
charge_who(NOTHING), amount_col(0), chan_obj(NOTHING),
|
|
num_messages(0)
|
|
{
|
|
memset(name, 0, sizeof(name));
|
|
memset(header, 0, sizeof(header));
|
|
}
|
|
};
|
|
|
|
//! \struct comsys_t
|
|
// Data for storing user information for players on channels
|
|
struct comsys_t
|
|
{
|
|
//! DBREF of the user
|
|
dbref who;
|
|
|
|
//! Alias/channel pairs for this player
|
|
std::vector<com_alias> aliases;
|
|
|
|
comsys_t() : who(NOTHING) {}
|
|
};
|
|
|
|
//! \brief Save communication system data to disk
|
|
//! \param filename - file to use for for writing data
|
|
void save_comsys(UTF8 *filename);
|
|
|
|
//! \brief Save user aliases on a per-channel basis
|
|
//! \param fp - FILE pointer used for writing data
|
|
void save_channels(FILE *fp);
|
|
|
|
//! \brief Save channel data and some user state for each user on the channel
|
|
void save_comsystem(FILE *fp);
|
|
|
|
//! \brief Open file and load comsystem data from disk
|
|
//! \param filename - filename to open for reading
|
|
void load_comsys(UTF8 *filename);
|
|
|
|
//! \brief Delete comsystem information for the given dbref
|
|
void del_comsys(dbref who);
|
|
|
|
//! \brief Add player as an active member of the given channel
|
|
//! \param player - dbref of player to add
|
|
//! \param ch - comsys channel pointer to add to
|
|
void do_joinchannel(dbref player, struct channel *ch);
|
|
|
|
//! \brief Remove disconnecting player from the active user list for all channels
|
|
//! \param player - dbref to remove
|
|
void do_comdisconnect(dbref player);
|
|
|
|
//! \brief Remove player from the active user list of channel
|
|
//! \param player - dbref of the player to remove
|
|
//! \param channel - name of the channel
|
|
void do_comdisconnectchannel(dbref player, UTF8 *channel);
|
|
|
|
//! \brief Handle connecting player channel activations
|
|
//! \param player - dbref of the connecting player to process
|
|
void do_comconnect(dbref player);
|
|
|
|
//! \brief Remove objects with no channels or objects that are destroyed
|
|
void purge_comsystem(void);
|
|
|
|
//! Sort aliases for the given comsys_t data
|
|
void sort_com_aliases(comsys_t &c);
|
|
|
|
//! \brief Xmit messages to the listening objects on channel & log data
|
|
//! \param player - dbref of executor
|
|
//! \param ch - channel data to transmit the message on
|
|
//! \param msgNormal - message to send with comtitle
|
|
//! \param msgNoComtitle - message to send w/o comtitle
|
|
void SendChannelMessage(dbref player, struct channel *ch, UTF8 *msgNormal,
|
|
UTF8 *msgNoComtitle, bool bJoinLeaveMsg = false);
|
|
|
|
//! \brief Process '<alias> who' command to show online channel users
|
|
//! \brief player - enacting player
|
|
//! \brief ch - channel to display
|
|
void do_comwho(dbref player, struct channel *ch);
|
|
|
|
//! \brief Display message history for a particular channel
|
|
//! \param player - requesting player
|
|
//! \param ch - channel to determine history for
|
|
//! \param arg - number of historical messages to display
|
|
void do_comlast(dbref player, struct channel *ch, int arg);
|
|
|
|
//! \brief Process a player request to temporary leave a channel
|
|
//! \param player - player to remove
|
|
//! \param ch - channel to remove the player from
|
|
void do_leavechannel(dbref player, struct channel *ch);
|
|
|
|
//! \brief Process a channel removal for player ("delcom")
|
|
//! \param player - player to remove
|
|
//! \param channel - channel name to remove
|
|
//! \param quiet - show messages or not
|
|
void do_delcomchannel(dbref player, UTF8 *channel, bool bQuiet);
|
|
|
|
//! \brief Clear all channel subscriptions for the enactor ("clearcom")
|
|
void do_clearcom(dbref executor, dbref caller, dbref enactor, int eval, int key);
|
|
|
|
//! \brief Add a new channel subscription/alias for the enactor
|
|
void do_addcom(dbref executor, dbref caller, dbref enactor, int eval, int key, int nargs,
|
|
UTF8 *arg1, UTF8 *arg2, const UTF8 *cargs[], int ncargs);
|
|
|
|
//! \brief Process a request to set a channel header
|
|
//! \param player - player requesting the change
|
|
//! \param channel - channel name to change
|
|
//! \param header - new header to use
|
|
void do_cheader(dbref player, UTF8 *channel, const UTF8 *header);
|
|
|
|
//! \brief Locate a channel structure by channel name
|
|
//! \param channel_name - name of channel to locate
|
|
//! @return struct channel pointer or nullptr if not found
|
|
struct channel *select_channel(const UTF8 *channel_name);
|
|
|
|
//! \brief Locate player in the user list for the given channel
|
|
//! \param ch - channel data to search
|
|
//! \param player - dbref of the player to locate
|
|
//! @return nullptr if not found, or struct comuser pointer
|
|
struct comuser *select_user(struct channel *ch, dbref player);
|
|
|
|
//! \brief Validate alias limits of 1-5 characters, no spaces, no ANSI
|
|
//! \param pAlias - incoming alias
|
|
//! \param nValidAlias - return size of the valid alias
|
|
//! \param bValidAlias - is alias valid or not
|
|
//! \return new alias data or nullptr on failure
|
|
UTF8 *MakeCanonicalComAlias(const UTF8 *pAlias, size_t *nValidAlias,
|
|
bool *bValidAlias);
|
|
|
|
//! \brief Purge channels owned by player. Internal cleanup called from db.c
|
|
//! \param player - dbref of cleanup target
|
|
void do_channelnuke(dbref player);
|
|
|
|
//! \brief Process comsys related commands 'alias <cmd>' (from command.cpp)
|
|
//! \param who - enactor
|
|
//! \param cmd - command to process
|
|
//! \return true to continue searching command matches, false to stop
|
|
bool do_comsystem(dbref who, UTF8 *cmd);
|
|
|
|
//! \brief Check if player can join a channel
|
|
//! \param player - player to check for join access
|
|
//! \param chan - channel to check
|
|
//! \return true if allowed, false if denied
|
|
bool test_join_access(dbref player, struct channel *chan);
|
|
|
|
//! \brief Check if player can transmit on a channel
|
|
//! \param player - player to check for join access
|
|
//! \param chan - channel to check
|
|
//! \return true if allowed, false if denied
|
|
bool test_transmit_access(dbref player, struct channel *chan);
|
|
|
|
//! \brief Check if player can receive channel transmission
|
|
//! \param player - player to check for join access
|
|
//! \param chan - channel to check
|
|
//! \return true if allowed, false if denied
|
|
bool test_receive_access(dbref player, struct channel *chan);
|
|
|
|
#define CHANNEL_PLAYER_JOIN (0x00000001UL)
|
|
#define CHANNEL_PLAYER_TRANSMIT (0x00000002UL)
|
|
#define CHANNEL_PLAYER_RECEIVE (0x00000004UL)
|
|
#define CHANNEL_OBJECT_JOIN (0x00000010UL)
|
|
#define CHANNEL_OBJECT_TRANSMIT (0x00000020UL)
|
|
#define CHANNEL_OBJECT_RECEIVE (0x00000040UL)
|
|
#define CHANNEL_LOUD (0x00000100UL)
|
|
#define CHANNEL_PUBLIC (0x00000200UL)
|
|
#define CHANNEL_SPOOF (0x00000400UL)
|
|
|
|
// Connected players and non-garbage objects are ok.
|
|
//
|
|
#define UNDEAD(x) (Good_obj(x) && ((Typeof(x) != TYPE_PLAYER) || Connected(x)))
|
|
|
|
#endif // !COMSYS_H
|