PDA

View Full Version : Player to Player whisper



Archmage
April 25th, 2008, 05:29
I've made what I think is a fairly workable Player to Player whispering system, which also includes GM review. I've seen lots of requests for such a thing, but no actual implementations (maybe I'm just not looking hard enough).

This has gone through about 12 hours of development and testing, and I haven't found any serious problems yet, but since this is the first release I'm considering it to be in a "beta" stage. So use at your own risk.


I'm attaching the modified Lua files, so if you are currently using the base d20 ruleset, you can just replace the existing files with those in the .zip file. If you've got other changes to your ruleset in either chatmanager.lua or chat_chat.lua, here's how to add this one.

1) Remove or comment out the processWhisper(params) function in your chatmanager.lua script

2) Copy and Paste the following code in its place.


-- Called from: chat_chat.onReceiveMessage()
function deliverWhisper(params)

local whisper = {};
local sepIndex = 0;
local recipient = "";
local sender = "";

-- parse sender string
sepIndex = string.find(tostring(params.sender), "¦");
recipient = string.sub(params.sender,4,sepIndex-1);
sender = string.sub(params.sender,sepIndex+1,string.len(par ams.sender)-1);

whisper.sender = "[w] " .. sender;
whisper.text = params.text;
whisper.font = "msgfont";

control.deliverMessage(whisper, recipient);

-- Convert username to label
local reciever = User.getCurrentIdentity(recipient);
reciever = User.getIdentityLabel(reciever);

local msg = {};
msg.text = "[w] " .. tostring(sender) .. " -> " .. reciever .. ": " .. params.text;
msg.font = "msgfont";
ChatManager.addMessage(msg);

end

function processWhisper(params)
local msg = {};
msg.font = "msgfont";

local spacepos = string.find(params, " ", 1, true);
if spacepos then
local recipient = string.sub(params, 1, spacepos-1);
local originalrecipient = recipient;
local message = string.sub(params, spacepos+1);

-- Find user
local user = nil;

for k, v in ipairs(User.getAllActiveIdentities()) do
local label = User.getIdentityLabel(v);
if string.lower(label) == string.lower(originalrecipient) then
-- Direct match
user = User.getIdentityOwner(v);
if user then
recipient = label;
break;
end
end
end

if user then
msg.text = message;
if User.isHost() then

msg.sender = "[w] GM";
control.deliverMessage(msg, user);

msg.sender = "[w] -> " .. recipient;
control.addMessage(msg);

else
--Use "<w>" as special tag for whispers. Gets picked up by
-- onRecieveMessage() in chat_chat.lua;
msg.sender = "<w>" .. user .. "&#166;" .. User.getIdentityLabel();

ChatManager.deliverMessage(msg, "");

msg.sender = "[w] -> " .. recipient;
control.addMessage(msg);

end

return;
end

if User.isHost() then
msg.font = "systemfont";
msg.text = "Recipient not found \rUsage: /w [recipient] [message]";
control.addMessage(msg);
else
ChatManager.processWhisperGM(params);
end

return;
else
ChatManager.processWhisperGM(params);
end

end

function processWhisperGM(params)
local msg = {};
msg.font = "msgfont";

if not User.isHost() then
msg.sender = "[w] " .. User.getIdentityLabel();
msg.text = params;
control.deliverMessage(msg, "");

msg.sender = "[w] -> GM";
control.addMessage(msg);
end

return;

end
-- end P2P whisper mod

3) Also in chatmanager.lua, add the following lines to the onInit() function


registerSlashHandler("/w", processWhisper);
registerSlashHandler("/wg", processWhisperGM);


4) In chat_chat.lua, add the following code at the bottom of the file. If you already have an onReceiveMessage(msg) function in your chat_chat.lua script (from some other ruleset or mod), simply add the bold lines to the top of the function.

function onReceiveMessage(msg)

if string.find(msg.sender, "<w>") == 1 then
ChatManager.deliverWhisper(msg);
return true;
end

return false;
end



Usage instructions

As the GM
If you are the host (aka GM), whispering works basically like it always did. Type /w [recipient] [message] to send the message to the specified recipient. They will see "[w] GM: message text" in their chat window.

Whenever a player sends a whisper to another player, you will see a chat message something like [w] Cat -> Dog: What's up. The sender is always listed first, and then the recipient, followed by the message.

As a player
If you are a client (aka a player), whispering to another player works much like the GM's whisper command. Type /w [recipient] [message] to send a message to the specified recipient. If you do not specify a valid recipient, the whisper will be sent to the GM.

For example:
If player Cat types /w Dog What's up. Dog will receive a whisper that says [w] Cat: What's up.

If Cat types /w What's up. The GM will see [w] Cat: What's up. This is because "What's" is not a valid recipient name.

Players should use the /wg command if they wish to whisper the GM, even though the normal whisper command will work. This is because if the first word of your message to the GM happens to be a valid recipient name, the /w command will send the message to that recipient instead of the GM. The /wg command always sends to the GM.

Important note
The auto-fill function for the recipient name no longer works. You can still type a partial match for the recipient name and then press tab to auto-complete the name. If the command does not specify a full valid character name, then the message will be sent to the GM.

For example:
Under the normal d20 ruleset, you could type /whisper D What's up, and your message would be sent to Dog (assuming Dog was the only valid character whose name starts with D). Because of the way this mod works, you must now type the "D" then press the tab key to auto-complete the name before you type the rest of the message, otherwise the message will go to the GM.


If anybody finds any repeatable problems, please let me know.

Malovech
April 25th, 2008, 19:05
Excellent job Archmage, I have been wanting functionality like this since using FG for the very first time. Your effort is greatly appreciated.

Dachannien
April 26th, 2008, 08:14
If I'm wrong on this, let me know, but for those who like this mod but would rather let players whisper to each other without GM eavesdropping, you can comment out the "ChatManager.addMessage(msg);" line at the bottom of the first function in the first box in Archmage's post. (Technically, one should comment out the five preceding lines of code also, but it's not strictly necessary.)

Anyway, nice work! :)

Archmage
April 26th, 2008, 09:00
If I'm wrong on this, let me know, but for those who like this mod but would rather let players whisper to each other without GM eavesdropping, you can comment out the "ChatManager.addMessage(msg);" line at the bottom of the first function in the first box in Archmage's post. (Technically, one should comment out the five preceding lines of code also, but it's not strictly necessary.)

Anyway, nice work! :)
Yes, you could actually comment out everything from "-- Convert username to label" to the end of the deliverWhisper() function if you wanted to disable GM review.

It also wouldn't be hard to make a toggle for it either. I may do that in the future.

Destan
April 26th, 2008, 12:44
Great work Arch! I know SW's reasoning as to why PC-to-PC whispering wasn't in the standard release, but I remained unconvinced. This was a needed mod!

Thank you!

D

Archmage
April 26th, 2008, 22:08
Ok, one bug found.

If the recipient has a space in their name, then any message sent to them will go to the GM instead. This is a result of the fact that the name parser works by finding the first space in the parameters passed to the whisper command, which is part of the character name in this case. This results in an incomplete name, and so no recipient match is found.

Obviously the easiest work around is to use an underscore instead of a space in your character name.

arnon
May 6th, 2008, 17:49
Thanks for this script Archmage, i'm going to add it as i'm getting tried of whispering back and forth for my players ;)


Ok, one bug found.

If the recipient has a space in their name, then any message sent to them will go to the GM instead. -snip-

So does this mean that pressing Tab to auto complete the name in the whisper does not work? So if a character has two names they'll either have to add an underscore or leave just one name?

Thanks

Archmage
May 7th, 2008, 01:38
So does this mean that pressing Tab to auto complete the name in the whisper does not work? So if a character has two names they'll either have to add an underscore or leave just one name?

Thanks
The Tab auto-complete itself still works, it fills in the name properly. But if there's a space in the name, the /whisper command does not function properly because it divides the name from the message by finding the first space character in the command. Simply using an underscore instead of a space for your name solves the problem.

I'm currently working on a Star Wars Saga Edition ruleset, so when I have some time I'll fix the issue. If somebody else wants to fix it, I have no problem with that either. All you really need to do is make the command parser first search for a different character, like a colon. If it finds one of those, treat everything before it as the name, treat everything after it as the message. If it doesn't find one, use the first space as the separator for name and message.

VenomousFiligree
May 30th, 2009, 08:51
Could this be made into an extension?

Ikael
May 30th, 2009, 13:58
This is very nice tool! I will come in handly, thank you very much!
About the whitespace problem, I modified the processWhisper function that it will cut the receipent at first ':' instead on first whitespace, and modified that autocomplete will add ': ' to end. That's how whitespaces are allowed (in my games, there are always thousand whitespaces in every character's names).

Doswelk
June 3rd, 2009, 09:39
This is very nice tool! I will come in handly, thank you very much!
About the whitespace problem, I modified the processWhisper function that it will cut the receipent at first ':' instead on first whitespace, and modified that autocomplete will add ': ' to end. That's how whitespaces are allowed (in my games, there are always thousand whitespaces in every character's names).

Can you post the changes you made (just the lines you changed should be enough)

Ta

Ikael
June 3rd, 2009, 16:05
This makes it possible to have whitespaces in names and autocompletion works (note that now names should not have : -marks). Both lines of code are found from chatmanager.lua



function processWhisper(params)
...
local spacepos = string.find(params, ":", 1, true); -- ":" instead of " "
...




function doAutocomplete()
...

-- Check identities
for k, v in ipairs(User.getAllActiveIdentities()) do
...
if label and string.find(string.lower(label), string.lower(search), 1, true) == 1 then
local replacement = remainder .. label .. ": "; -- .. ": " added to end of the row
...


The things after this is that every tab autocompletion is used there will be : mark after the name, but that's better than unable to use autocompletion at all.

VenomousFiligree
June 3rd, 2009, 16:46
Could this be made into an extension?

Is that a no then? :)

Debinani
September 23rd, 2009, 21:06
So, out of curiosity, why did you remove the partial-name loop? Does that not work properly on the clients?