ID:1691638
 
There's an IRC server that can handle all of this. I am currently working on a .DLL file (if I can figure out how to make it properly).

I have a PHP bot that can send and receive commands from this IRC server. It didn't prove efficient to run in a web browser by many people (because PHP sucks in some cases).

I converted this PHP bot to C# for another project that I released and a lot of people seem to use now.

Now, I need to convert this C# (or better yet, PHP since the C# only receives and doesn't send) in to C++. I need to convert it in a way that it returns strings to the game to be printed to the output. However, I have little knowledge of .DLLs. In fact, just today, I got it to call a function that returns a string. That's it. I don't even know PHP and I managed that.

Request
If anyone would like a crack at converting the C# code (or PHP, whichever you request) in to a .h/.cpp or whatever is needed and then send it to me to compile and/or edit, that'd be nice.

Question
Would a .DLL run on the server or the client if you called it on the client? Because sending too many commands from one connection will, as a result, get you locked out. With there being a lot of people using it, it'd be best if this were possible to run on the client side.

Tips?
I don't need any "different" ways of going about this. We've been discussing this among ourselves for quite a while now. First it was world.Export(), next it was sending data through .txt, next it was PHP interaction, now we're at IRC, which seems to be the best route to go by a long shot.

I'm hard set for creating IRC capabilities in BYOND by the use of a .DLL. My only concern is, how the hell do .DLLs run on BYOND? If I perform call(src,...) does it still perform the socket via the server's IP or the client's IP?

"Can you test it yourself?" Nope. Because I don't know how to create a .DLL properly for BYOND. I've never, in the many years I've been here, "had" to create one. Nor do I feel like waiting for a feature request, which, as research shows, has not been implemented for years so far. So, I'll make my own. :)

TLDR...

I'll post the C# and PHP code below for all those who would like to contribute their C++ knowledge in terms of creating a .DLL for BYOND by converting the code. I like to keep it all in one file and with little lines (code condensing with efficiency).

So, it won't be too much of an eyesore and is easily understood. In fact, the C# version is, by far, a lot more easily understood. Because I wrote it from scratch after having fully understood the PHP one.

If you have any tips on how to create the .DLL myself, reply. That's what I wrote in a nutshell. I'm beyond serious about this post and I'll QQ to mods if I have to just to keep it clean.

Still too long? Don't read.
Would a .DLL run on the server or the client if you called it on the client?
It's server-sided only (i.e. the DD or DS instance hosting the files).
I have little knowledge of C# but promising in C++. How about you post the code?
In response to Mr_Goober
Mr_Goober wrote:
Would a .DLL run on the server or the client if you called it on the client?
It's server-sided only (i.e. the DD or DS instance hosting the files).

Seems like I'll have to go about this another way then. We've gotten so far. We've finally integrated an auth system for accounts and other external stuff. All we need now is a way to chat server-to-server without bandwidth issues. My question is, if the servers are on the same network, would that, at all, consume bandwidth?
In response to Wissam
Wissam wrote:
I have little knowledge of C# but promising in C++. How about you post the code?

It's pointless now since it wouldn't run on the client. In the end, the server would just get locked out from connecting to the IRC too many times or from sending too many commands.
In response to Xirre
Xirre wrote:
My question is, if the servers are on the same network, would that, at all, consume bandwidth?

If you're addressing your LAN addresses, it would not consume carrier bandwidth. Private address cannot route via the internet.

If you're addressing a public ip, and using NAT, as long as you don't have multiple devices with different IP addresses (that are in different subnets), you shouldn't either. A standard router should see a request to itself and decide to not forward that request outside the network.

In response to Pirion
Pretty much a world.Export("127.0.0.1:3000?query"). This just seems problematic to send these messages from server to server seeing as there could be hundreds of different possible channels. Even more. And I'd rather not iterate through each user on each server. I'd also rather not make the channel datum on each server, since that could lead to RAM issues in the long-run. I'm not sure how to go about this.

Channel handler...
var
list
ChanRoom
chanRooms = new/list
dispChans = new/list

obj
StatVerbs
Create_Channel_OBJ = new/obj/StatVerbs/Create_Channel

mob
player
var
ChanRoom
currRoom

proc
Join(ChanRoom/cR)
if(src.currRoom != cR) // If their current room does not equal the room they are currently in...
if(src.currRoom) // If they are currently in a room, which they should be at all times...
src.currRoom.players -= src // Then subtract them from the room's player list they are currently in...
if(src.currRoom != "Lobby") // and if they are in the Lobby...
src.ChanMsg("[src.name] has switched channels") // Don't flood their chat with nonsensical chat switching
src.currRoom = cR
src.ChanMsg("[src.name] has joined")
src.currRoom.players += src
src.DirectMsg("You are now connected to <b>[src.currRoom]</b>.")
else // Else, tell them they can't join the same room.
src.DirectMsg("You are already connected to that channel.")

obj
StatVerbs
Create_Channel
Click()
if(istype(usr,/mob/player))
var/mob/player/p = usr
if(p.currRoom != p.name + "\'s Channel")
if(alert(p, "Would you like to leave [p.currRoom] and create \"[p.name]\'s Channel\"?","Channel Creation", "Yes", "No") == "Yes")
var/ChanRoom/cR = new(p)
if(cR)
p.Join(cR)
else
p.DirectMsg("Failed to create the channel. Perhaps it already exists elsewhere?")


// This is the Datum that controls chat rooms.
// Passing New() to this will create a Channel Room based on the passed mob's name.
// If the mob is not of type mob/player, it will not accept the type.
// Passing nothing to it will result in the New() proc to create a Channel named "Lobby".
// This should only be done at world/New()
ChanRoom
parent_type=/obj

var
mob
player
owner
list
players = new/list

New(mob/player/_owner)
if(!_owner)
if(!chanRooms["Lobby"])
src.name = "Lobby"
chanRooms[src.name] = src
dispChans += src
else
del src
else
if(!chanRooms[_owner.name + "\'s Channel"])
src.name = _owner.name + "\'s Channel"
chanRooms[src.name] = src
dispChans += src
else
del src
..()

Click()
Join()

proc
Join()
if(istype(usr,/mob/player))
var/mob/player/p = usr
if(alert(usr, "Would you like to leave [p.currRoom] and join [src]?","Channel Switch", "Yes", "No") == "Yes")
p.Join(src)


Chat commands (placed in procs in case in the future we'd like to easily change up how chat is displayed)
mob
player
proc
// Typically will be used for admin-based commands to inform everyone of something
WorldMsg(var/msg as text)
world << msg

// Used for channel-based messaging
ChanMsg(var/msg as text)
src.currRoom.players << msg

// Will be used for informing a user directly of something or private messaging someone else.
DirectMsg(var/msg as text)
src << msg

FormatChat(var/playerName, var/playerColor, var/_text)
var/msg = "<b><font color = \"[playerColor]\">[playerName]</b>: [_text]"
return msg


Currently it will send messages to all players within their datum. There can only be 1 channel per user and it's destroyed after the owner logs out. When the owner logs out, all users are then moved back to the Lobby.

Because of some limitations with BYOND, the server has to be split. However, with no exceptions, there must be a way to chat between servers and differentiate between channels as well.
Thinking about the problem, I would half build the channels on each server. The source server would be responsible for tracking the hosts that need access to the channel. The local servers would maintain internal lists of who would be receiving these messages.

With this build, you can either a) add each user to the source list or b) on the local copy only, and send a subscribe, unsubscribe when needed.

For the lobby, I would add a way for these servers to find each other (mysql maybe) and designate the first up to take this role.
I Hate C++, or why I made call()() work with .NET DLLs

Shameless plug, but this might be of use to you.
In response to Topkasa
Topkasa wrote:
I Hate C++, or why I made call()() work with .NET DLLs

Shameless plug, but this might be of use to you.

I already read it last week.