Pichat Developer Documentation
Learn how to write own chat features and awake the chat with more life.
This document is for developers who want to extend their chat and gives you an
introduction of how to write plugins and communicate with chat servers. There is
also a software development kit (
Pichat SDK) for download which comes with
libraries, examples and unit tests.
Pichat supports plugins to add additional features to chat and web server.
Plugins can be used for a variety of things, from handling chat actions such as
users joining a chatroom up to chat bots that interact independently with users
in the chat.
What you need to do in your own plugin: Basically are all plugins shared
libraries that implement a C++ interface and export a function called
CreatePlugin().
Here's an example source code:
namespace Plugin
{
class CImplementation : public IPluginInterface
{
public:
CImplementation(IApplicationInterface* pApi)
{
//TODO: more code here
}
virtual ~CImplementation() { }
virtual void DeleteThis() const { delete this; }
virtual const char* GetVersionName() const { return "Example.Simple"; }
virtual const char* GetVersionDescription() const { return "Chat plugin example"; }
virtual int GetVersionNumber() const { return 0x000101; } //note: v0.1.1
};
};
PLUGINEXAMPLE_EXPORT IPluginInterface* CreatePlugin(IApplicationInterface* pApi)
{
return new Plugin::CImplementation(pApi);
}
When a plugin is created it receives a pointer to an application interface with
which it has access to chat functionality ('pApi' in code above). It's good to
have a look at existing plugins and investigate how they work. There are two
libraries
PichatCore and
SharkEngine to assist you in writing plugins.
Notes: All plugins are loaded on application startup. The plugin version name
should follow the format 'category.type', where category describes the offered
service such as 'bot' or 'webcam'.
Pichat supports a text chat protocol which makes it very easy to access chatrooms
on a chat server. The idea is to make the implementation of small, simple chat
clients possible and also to simplify the communication between multiple chat
applications.
What you need to do in your client: Connect to a chat server and send the login
sequence below as first line, all arguments are optionally. A chat server
identifies itself by sending "PICHAT" (hex 0x50 0x49 0x43 0x48 0x41 0x54) as
first six bytes of identification, otherwise terminate connection immediately. If
you are successfully connected show received non empty text lines to the user and
send typed in text lines to the server. The chat server does the rest and
provides you with a complete text description of what's happening in the chat. No
parsing required, easy peasy lemon squeezy.
| Syntax: | PICHAT/TEXTCHAT nickname, authentication, chatroom, language, |
| useragent, format, localtime, timehours |
| |
| Arguments: |
| nickname | = | nickname of user (none for interactive login mode), |
| | alternative nicknames can be separated by colon |
| authentication | = | optional user name and password of registered user, |
| | values are separated by colon and then base64 encoded |
| chatroom | = | name of chatroom (none for default chatroom) |
| language | = | preferred language, ISO639 (none for English), |
| | multiple languages can be separated by colon |
| useragent | = | name of user agent (none for unnamed text chat) |
| format | = | text format, one of the following: |
| | RAW = raw text, no text conversion (default) |
| | TEXT = plaintext without colors and bold |
| | ANSI = text with colors and bold |
| | XML = text with lots of meta information |
| localtime | = | current time as hh:mm:ss (default is 00:00:00) |
| timehours | = | hours format, 12 or 24 (default is 24) |
|
| |
| Examples: | PICHAT/TEXTCHAT Moak |
| PICHAT/TEXTCHAT Moak, YWxhZGRpbjpvcGVuc2VzYW1l |
| PICHAT/TEXTCHAT Moak,, Flirt, de, talker, TEXT, 14:30:05, 24 |
First example connects to a chat server using the nickname 'Moak'. The second
example connects as registered user with the user name 'aladdin' and password
'opensesame'. The third example connects a text client with German language to
the chatroom 'Flirt' and also sets a local time.
Notes: The protocol is line based plaintext (8-bit-characters), each line is
separated through \r\n (CRLF). Default listening port of a chat server is 9009
TCP. Under no circumstances must the login sequence be extended with more
arguments (which would lead to incompatibility), application specific extensions
shall go into separate lines.
Pichat offers a simple chat status query, you can check if a chat server is
online and see how many users are there. Connect to a chat server and send the
status sequence below. A chat server identifies itself by sending "PICHAT" as
first six bytes of identification, then returns version information, server
status (users, activity, dedicated, chat mode, lag), extended server status
(users-served, traffic, uptime, interests) and another line with server name and
welcome message. After that the client will be disconnected.
| Syntax: | PICHAT/STATUS user-identification, name, language, useragent |
| |
| Arguments: |
| user-identification | = | identification of user |
| name | = | name of user or chat server |
| language | = | preferred language, ISO639 (none for English), |
| | multiple languages can be separated by colon |
| useragent | = | name of user agent (none for unnamed client) |
|
| |
| Examples: | PICHAT/STATUS moak@unknown, Moak |
| PICHAT/STATUS moak@unknown, Moak, sv, mybot/1.0 (+http://myserver) |
First example queries chat status as user 'Moak', the second example requests
chat status in Swedish language and includes an detailed user agent description.
Here's a typical chat server response:
PICHAT
!SERVER_VERSION Pichat Server v0.4.2 b27
!SERVER_STATUS 4,38,0,1,0
!SERVER_STATUS_EXTENDED 64,64738,6510,chat,music,pizza
!SERVER_INFO Moak's Chat,Welcome to Moak's chat
!CONNECT_STATUS 203 Done, end of connection
Notes: Clients should not update the chat status more than once per minute to
avoid flooding a chat server. Alternatively, the chat status is also available as
web page and RSS feed (XML format). For further information please see
Chat Configuration.
You enjoy creating software with graphics and networking. Why not working
together and improve this project together? Pichat is technically based on C++,
STL and a platform independent core that runs on Linux, BSD and Windows. Doesn't
that sound like fun programming to you... :)
- Plugin development:
Write chat plugins for all kind of nice stuff, improve chat and webchat with
new features. Basic programming skills in C++ required.
- Client development:
Write native code for a specific platform. Good experience in user interface
programming required, for example on Linux, Symbian or Windows.
- PichatCore development:
Write platform independent code and design new chat features. Good knowledge
of peer-to-peer networks (P2P) and chat systems required.
From big help would currently be plugin developers and furthermore a web designer
(visuals really need an update from a stylish hand). See what's planned next on
the
Road Map.
The following diagram shows an example design for a peer-to-peer chat application.
Usually an application is client and server at once, plus a graphical user
interface on top. Basically the same design is also used in existing Pichat
software. Lines show HasA relationships between classes and not inheritance, an
asterisk emphasises a many-to-one relationship.
CPichat
|
. . . . . . | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
DATA CPichat ________ CPichat _________________________________________________________
PART MainFrame MainData | |
| | | | CPichatClientManager CPichatServerManager
| | | | | |
| | | |___ CPichatMain |___ CSocketClientPreferences |___ CSocketServerPreferences
| | | | Preferences | |
| | | | |___*CClientConnection |___ CSocketServerPichat
| | | |___ CPichatGui |___ CSocketClientPichat |___ CSocketServerHttp
| | | | Preferences |___ CSocketHelperDns |___ CSocketObserverPichat
| | | |
| | | |___ CPichat3d
| | | Preferences
| | |
. . . . . | | | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
| | |
GUI | | |_____ CSystemTray
PART | |
| |_______ CPichatDialogManager ___________________________________________________
| | | |
CPichat CPichat *CPichat |___ CPichat
Dialog3D DialogMain DialogChat | DialogAbout
| | |
|___*CPichatViewConnection |___ CPichatViewConnection |___ CPichat
| |___ CTextBoxChat |___ CTextBoxChat | DialogStatus
| |___ CEditBoxChat |___ CEditBoxChat |
| |___ CListBoxSide |___ CListBoxSide |___ CPichat
| DialogOptions
|___ CPichatViewStatus
|___ CPichatViewContacts
|___ CPichatViewButtons
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 1: Example class design
While the 'DATA PART' typically is implemented platform independent and shared
between different platforms, the 'GUI PART' is implemented platform specific to
match best to the native user interface and therefore offers a native look and
feel. A special case is the class CPichat that kicks off the application
framework, it is different for each purpose.
Pichat is created with the idea of agile software development in mind: First make
it work, then make it better. So it's no big surprise that one of the biggest
design goal for Pichat is maintainability (design to fit the needs, but at the
same time love and expect changes). There are two main software design factors I
am personally looking at: First, which functionality does a class offer, is its
(public) interface intuitive and safe to use? Secondly, how does the information
flow work, is it elegant and efficient?
This diagram shows information flow of text input with an example. Typically text
input comes from a view, a client sends it then to a server, data is being
processed there, again received by the client and finally text output is shown in
a chat window. Both client side and server side are able to process chat commands.
CClientConnectionView CClientConnection
::SendInput() ---------> ::SendInput() -----------------------
| |
\ / \ /
CClientConnection CSocketClient
::ProcessChatCommand() --> ::SendInput()
|
------------------------|
| |
| \ /
| CSocketClient CSocketNode
| ::Send() ------------ TCP --> ::OnReceiveLine()
| |
| \ /
| CSocketNode CSocketServer
| ::ProcessChatCommand() --> ::SendAll()
| | |
| \ / |
| CSocketClient CSocketNode |
|--------------- ::OnReceiveLine() <-- TCP --- ::Send() <-----------------------
| |
| |
| |
| \ /
| CSocketClient
\ / ::ProcessChatAction()
CClientConnectionView CClientConnection |
::OnChatText() <----------- ::OnChatClientCallback() <-------
|
\ /
CClientConnectionStatusView CClientConnectionManager
::OnChatNetwork() <-------- ::SendAllStatus()
Figure 2: Example information flow of text input
The development philosophy behind Pichat.
- Support communication + privacy + free information exchange.
- Improve technology. Are open minded for new ways, learn and are curious!
- Share information. Team work and good processes make life easier!
- Have fun in life. Keep motivation high all the time!
Let me explain what I mean with good processes. I think that processes are more
important than the organisation or the structure of a system (e.g. software
processes are in my experience more relevant than the hierarchy of a development
group). A structure is always something static that tries to organise the
information flow and the purpose of individuals inside. But what we actually want
to achieve is creating an efficient system that delivers maximised output
(software in our case).
Let's see it from this perspective and accordingly optimise information flow and
its key components: Such as information distribution, communication between
individuals, organisation of team work and safe guards to minimise risks or
problems that show up on the way. Structures are better built on processes than
the other way around (e.g. when you wrongly build processes on existing
structures you have already made design decisions that weaken structural self
organisation, possibly limit information flow and efficiency of team work). In a
similar way are individuals better defined by their tasks and strengths rather
than by a position (e.g. there is generally the sneaking danger of hierarchical
structures defining themself by their position and less by the real purpose they
fullfill or the processes that would otherwise be applied, people in powerful
positions are tempted to put personal interests over goals of the whole system).
Organisation of team work is best when different planing parties (e.g. technical
and non technical planing) work equally together and define their tasks as a
looking ahead assistance for others. For example take commercial software projects
which often suffer from "management" trying to control instead of aiding the
creative design processes. As a result are problems and product shortcomings
often denied until it is too late. A proper management would requires that
different planing parties work together, including engineers and customers.
There is also a deeply rooted misunderstanding of what "software engineering" is,
I believe it's a design discipline and not a deterministic engineering discipline
at all (software engineers spend more time on software design decisions than on
building software). However, a bigger problem than technical hurdles are usually
individuals and the lack of communication between them. For example let five
people work together, watch how misunderstandings and dislikes grow and opinions
collide in a non productive way. Let's face it, we all have to deal with
incompetence and insensitivity, hopefully not every day, but we need to develop
strategies to deal with it and also how to integrate problematic persons into our
day to day work. Some tips: allow people to create a personal relationship to
you, explore problems and feelings in a personal dialogue (not in front of
others). A few more psychological aspects to look at: a lack of clearness and
security cause humans to feel unhappy, a lack of vision and purpose causes humans
to disconnect from a project. But on the other hand (a manageable level of)
responsibility and challenge are directly related to higher productivity and joy.
Ideally, there should be processes in place to monitor and improve the overall
efficiency and health state of a system (or 'Wohflühlstatus' in German, a word
that describes the feeling-good-state of a complete system and its individuals,
it's an empathic expression that underlines the importance of the human side).
For example take a development group that produces output but is unhappy, it will
sooner or later collapse or needs time to raise to a next level. On the other
hand take a motivated but inefficient development group, it will produce no
satisfying output and needs time to raise productivity and quality. There is
generally nothing you can do against bad politics and wrong people in powerful
positions other than to de-power those people quickly (remember to focus on
building processes not structures).
Summing it up, I believe that software processes are utterly important for any
software project, to create an environment where ideas are allowed to be realised
and people enjoy working with each other.