github.imxd.top/rafael-santiago/cherry@v0.0.0-20161214151746-8ea42c6e9670/src/pkg/config/config.go (about)

     1  /*
     2  Package config "classify" (:P) a plain cherry file.
     3  --
     4   *                               Copyright (C) 2015 by Rafael Santiago
     5   *
     6   * This is a free software. You can redistribute it and/or modify under
     7   * the terms of the GNU General Public License version 2.
     8   *
     9  */
    10  package config
    11  
    12  import (
    13  	"crypto/md5"
    14  	"fmt"
    15  	"io"
    16  	"net"
    17  	"sort"
    18  	"strings"
    19  	"sync"
    20  )
    21  
    22  // RoomMisc gathers the misc options for a room.
    23  type RoomMisc struct {
    24  	listenPort                int16
    25  	joinMessage               string
    26  	exitMessage               string
    27  	onIgnoreMessage           string
    28  	onDeIgnoreMessage         string
    29  	greetingMessage           string
    30  	privateMessageMarker      string
    31  	maxUsers                  int
    32  	allowBrief                bool
    33  	floodingPolice            bool
    34  	maxFloodAllowedBeforeKick int
    35  	allUsersAlias             string
    36  	publicDirectory           string
    37  }
    38  
    39  // RoomAction gathers the label and the template (data) from an action.
    40  type RoomAction struct {
    41  	label    string
    42  	template string
    43  }
    44  
    45  // RoomMediaResource gathers the label, template (data) and uri from a generical resource (until now, images only).
    46  type RoomMediaResource struct {
    47  	label    string
    48  	template string
    49  	url      string
    50  }
    51  
    52  // Message gathers a message that must be formatted and delivered.
    53  type Message struct {
    54  	From   string
    55  	To     string
    56  	Action string
    57  	//    Sound string
    58  	Image string
    59  	Say   string
    60  	Priv  string
    61  }
    62  
    63  // RoomUser is the user context.
    64  type RoomUser struct {
    65  	sessionID  string
    66  	color      string
    67  	ignoreList []string
    68  	kickout    bool
    69  	conn       net.Conn
    70  	addr       string
    71  }
    72  
    73  // RoomConfig represents in memory a defined room loaded from a cherry file.
    74  type RoomConfig struct {
    75  	mutex          *sync.Mutex
    76  	MainPeer       net.Listener
    77  	messageQueue   []Message
    78  	publicMessages []string
    79  	users          map[string]*RoomUser
    80  	templates      map[string]string
    81  	misc           *RoomMisc
    82  	actions        map[string]*RoomAction
    83  	images         map[string]*RoomMediaResource
    84  	//sounds map[string]*RoomMediaResource
    85  	ignoreAction   string
    86  	deignoreAction string
    87  }
    88  
    89  // CherryRooms represents your cherry tree... I mean your cherry server.
    90  type CherryRooms struct {
    91  	configs     map[string]*RoomConfig
    92  	servername  string
    93  	certPath    string
    94  	privKeyPath string
    95  }
    96  
    97  // NewCherryRooms creates a new server container.
    98  func NewCherryRooms() *CherryRooms {
    99  	return &CherryRooms{make(map[string]*RoomConfig), "localhost", "", ""}
   100  }
   101  
   102  // GetRoomActionLabel spits a room action label.
   103  func (c *CherryRooms) GetRoomActionLabel(roomName, action string) string {
   104  	c.Lock(roomName)
   105  	var label string
   106  	label = c.configs[roomName].actions[action].label
   107  	c.Unlock(roomName)
   108  	return label
   109  }
   110  
   111  // GetRoomUsers spits all users connected in the specified room.
   112  func (c *CherryRooms) GetRoomUsers(roomName string) []string {
   113  	var users []string
   114  	users = make([]string, 0)
   115  	c.Lock(roomName)
   116  	for user := range c.configs[roomName].users {
   117  		users = append(users, user)
   118  	}
   119  	c.Unlock(roomName)
   120  	return users
   121  }
   122  
   123  // GetRooms spits all opened rooms.
   124  func (c *CherryRooms) GetRooms() []string {
   125  	var rooms []string
   126  	rooms = make([]string, 0)
   127  	for room := range c.configs {
   128  		rooms = append(rooms, room)
   129  	}
   130  	return rooms
   131  }
   132  
   133  // GetUserConnection returns the net.Conn that represents an "user peer".
   134  func (c *CherryRooms) GetUserConnection(roomName, user string) net.Conn {
   135  	var conn net.Conn
   136  	c.Lock(roomName)
   137  	conn = c.configs[roomName].users[user].conn
   138  	c.Unlock(roomName)
   139  	return conn
   140  }
   141  
   142  // GetRoomActionTemplate returns the template data from an action.
   143  func (c *CherryRooms) GetRoomActionTemplate(roomName, action string) string {
   144  	c.Lock(roomName)
   145  	var template string
   146  	template = c.configs[roomName].actions[action].template
   147  	c.Unlock(roomName)
   148  	return template
   149  }
   150  
   151  // AddUser does what it is saying. BELIEVE or NOT!!!
   152  func (c *CherryRooms) AddUser(roomName, nickname, color string, kickout bool) {
   153  	c.configs[roomName].mutex.Lock()
   154  	md := md5.New()
   155  	io.WriteString(md, roomName+nickname+color)
   156  	id := fmt.Sprintf("%x", md.Sum(nil))
   157  	c.configs[roomName].users[nickname] = &RoomUser{id, color, make([]string, 0), kickout, nil, ""}
   158  	c.configs[roomName].mutex.Unlock()
   159  }
   160  
   161  // RemoveUser removes a user...
   162  func (c *CherryRooms) RemoveUser(roomName, nickname string) {
   163  	c.configs[roomName].mutex.Lock()
   164  	delete(c.configs[roomName].users, nickname)
   165  	c.configs[roomName].mutex.Unlock()
   166  }
   167  
   168  // EnqueueMessage adds to the queue an user message.
   169  func (c *CherryRooms) EnqueueMessage(roomName, from, to, action, image, say, priv string) {
   170  	c.configs[roomName].mutex.Lock()
   171  	c.configs[roomName].messageQueue = append(c.configs[roomName].messageQueue, Message{from, to, action, image, say, priv})
   172  	c.configs[roomName].mutex.Unlock()
   173  }
   174  
   175  // DequeueMessage removes from the queue the oldest user message.
   176  func (c *CherryRooms) DequeueMessage(roomName string) {
   177  	c.configs[roomName].mutex.Lock()
   178  	if len(c.configs[roomName].messageQueue) >= 1 {
   179  		c.configs[roomName].messageQueue = c.configs[roomName].messageQueue[1:]
   180  	}
   181  	c.configs[roomName].mutex.Unlock()
   182  }
   183  
   184  // GetNextMessage returns the next message that should be processed.
   185  func (c *CherryRooms) GetNextMessage(roomName string) Message {
   186  	c.configs[roomName].mutex.Lock()
   187  	var message Message
   188  	if len(c.configs[roomName].messageQueue) > 0 {
   189  		message = c.configs[roomName].messageQueue[0]
   190  	} else {
   191  		message = Message{}
   192  	}
   193  	c.configs[roomName].mutex.Unlock()
   194  	return message
   195  }
   196  
   197  // GetSessionID returns the user's session ID.
   198  func (c *CherryRooms) GetSessionID(from, roomName string) string {
   199  	if len(from) == 0 || !c.HasUser(roomName, from) {
   200  		return ""
   201  	}
   202  	c.configs[roomName].mutex.Lock()
   203  	var sessionID string
   204  	sessionID = c.configs[roomName].users[from].sessionID
   205  	c.configs[roomName].mutex.Unlock()
   206  	return sessionID
   207  }
   208  
   209  // GetColor returns the user's nickname color.
   210  func (c *CherryRooms) GetColor(from, roomName string) string {
   211  	if len(from) == 0 || !c.HasUser(roomName, from) {
   212  		return ""
   213  	}
   214  	c.configs[roomName].mutex.Lock()
   215  	var color string
   216  	color = c.configs[roomName].users[from].color
   217  	c.configs[roomName].mutex.Unlock()
   218  	return color
   219  }
   220  
   221  // GetIgnoreList returns all users ignored by an user.
   222  func (c *CherryRooms) GetIgnoreList(from, roomName string) string {
   223  	if len(from) == 0 || !c.HasUser(roomName, from) {
   224  		return ""
   225  	}
   226  	c.configs[roomName].mutex.Lock()
   227  	var ignoreList string
   228  	ignoring := c.configs[roomName].users[from].ignoreList
   229  	lastIndex := len(ignoring) - 1
   230  	for c, who := range ignoring {
   231  		ignoreList += "\"" + who + "\""
   232  		if c != lastIndex {
   233  			ignoreList += ", "
   234  		}
   235  	}
   236  	c.configs[roomName].mutex.Unlock()
   237  	return ignoreList
   238  }
   239  
   240  // AddToIgnoreList add to the user context some user to be ignored.
   241  func (c *CherryRooms) AddToIgnoreList(from, to, roomName string) {
   242  	if len(from) == 0 || len(to) == 0 || !c.HasUser(roomName, from) || !c.HasUser(roomName, to) {
   243  		return
   244  	}
   245  	c.configs[roomName].mutex.Lock()
   246  	for _, t := range c.configs[roomName].users[from].ignoreList {
   247  		if t == to {
   248  			c.configs[roomName].mutex.Unlock()
   249  			return
   250  		}
   251  	}
   252  	c.configs[roomName].users[from].ignoreList = append(c.configs[roomName].users[from].ignoreList, to)
   253  	c.configs[roomName].mutex.Unlock()
   254  }
   255  
   256  // DelFromIgnoreList removes from the user context a previous ignored user.
   257  func (c *CherryRooms) DelFromIgnoreList(from, to, roomName string) {
   258  	if len(from) == 0 || len(to) == 0 || !c.HasUser(roomName, from) || !c.HasUser(roomName, to) {
   259  		return
   260  	}
   261  	var index = -1
   262  	c.configs[roomName].mutex.Lock()
   263  	for it, t := range c.configs[roomName].users[from].ignoreList {
   264  		if t == to {
   265  			index = it
   266  			break
   267  		}
   268  	}
   269  	if index != -1 {
   270  		c.configs[roomName].users[from].ignoreList = append(c.configs[roomName].users[from].ignoreList[:index], c.configs[roomName].users[from].ignoreList[index+1:]...)
   271  	}
   272  	c.configs[roomName].mutex.Unlock()
   273  }
   274  
   275  // IsIgnored returns "true" if the user U is ignoring the asshole A, otherwise guess what.
   276  func (c *CherryRooms) IsIgnored(from, to, roomName string) bool {
   277  	if len(from) == 0 || len(to) == 0 || !c.HasUser(roomName, from) || !c.HasUser(roomName, to) {
   278  		return false
   279  	}
   280  	var retval = false
   281  	c.configs[roomName].mutex.Lock()
   282  	for _, t := range c.configs[roomName].users[from].ignoreList {
   283  		if t == to {
   284  			retval = true
   285  			break
   286  		}
   287  	}
   288  	c.configs[roomName].mutex.Unlock()
   289  	return retval
   290  }
   291  
   292  // GetGreetingMessage returns the pre-configurated greeting message.
   293  func (c *CherryRooms) GetGreetingMessage(roomName string) string {
   294  	c.configs[roomName].mutex.Lock()
   295  	var message string
   296  	message = c.configs[roomName].misc.greetingMessage
   297  	c.configs[roomName].mutex.Unlock()
   298  	return message
   299  }
   300  
   301  // GetJoinMessage returns the pre-configurated join message.
   302  func (c *CherryRooms) GetJoinMessage(roomName string) string {
   303  	c.configs[roomName].mutex.Lock()
   304  	var message string
   305  	message = c.configs[roomName].misc.joinMessage
   306  	c.configs[roomName].mutex.Unlock()
   307  	return message
   308  }
   309  
   310  // GetExitMessage returns the pre-configurated exit message.
   311  func (c *CherryRooms) GetExitMessage(roomName string) string {
   312  	c.configs[roomName].mutex.Lock()
   313  	var message string
   314  	message = c.configs[roomName].misc.exitMessage
   315  	c.configs[roomName].mutex.Unlock()
   316  	return message
   317  }
   318  
   319  // GetOnIgnoreMessage returns the pre-configurated "on ignore" message.
   320  func (c *CherryRooms) GetOnIgnoreMessage(roomName string) string {
   321  	c.configs[roomName].mutex.Lock()
   322  	var message string
   323  	message = c.configs[roomName].misc.onIgnoreMessage
   324  	c.configs[roomName].mutex.Unlock()
   325  	return message
   326  }
   327  
   328  // GetOnDeIgnoreMessage returns the pre-configurated "on deignore" message.
   329  func (c *CherryRooms) GetOnDeIgnoreMessage(roomName string) string {
   330  	c.configs[roomName].mutex.Lock()
   331  	var message string
   332  	message = c.configs[roomName].misc.onDeIgnoreMessage
   333  	c.configs[roomName].mutex.Unlock()
   334  	return message
   335  }
   336  
   337  // GetPrivateMessageMarker returns the private message marker.
   338  func (c *CherryRooms) GetPrivateMessageMarker(roomName string) string {
   339  	c.configs[roomName].mutex.Lock()
   340  	var message string
   341  	message = c.configs[roomName].misc.privateMessageMarker
   342  	c.configs[roomName].mutex.Unlock()
   343  	return message
   344  }
   345  
   346  // GetMaxUsers returns the total of users allowed in a room.
   347  func (c *CherryRooms) GetMaxUsers(roomName string) string {
   348  	c.configs[roomName].mutex.Lock()
   349  	var max string
   350  	max = fmt.Sprintf("%d", c.configs[roomName].misc.maxUsers)
   351  	c.configs[roomName].mutex.Unlock()
   352  	return max
   353  }
   354  
   355  // GetAllUsersAlias returns the "all users" alias.
   356  func (c *CherryRooms) GetAllUsersAlias(roomName string) string {
   357  	c.configs[roomName].mutex.Lock()
   358  	var alias string
   359  	alias = c.configs[roomName].misc.allUsersAlias
   360  	c.configs[roomName].mutex.Unlock()
   361  	return alias
   362  }
   363  
   364  // GetActionList returns a well-formatted "HTML combo" containing all actions.
   365  func (c *CherryRooms) GetActionList(roomName string) string {
   366  	c.Lock(roomName)
   367  	var actionList = ""
   368  	var actions []string
   369  	actions = make([]string, 0)
   370  	for action := range c.configs[roomName].actions {
   371  		actions = append(actions, action)
   372  	}
   373  	sort.Strings(actions)
   374  	for _, action := range actions {
   375  		actionList += "<option value = \"" + action + "\">" + c.configs[roomName].actions[action].label + "\n"
   376  	}
   377  	c.Unlock(roomName)
   378  	return actionList
   379  }
   380  
   381  func (c *CherryRooms) getMediaResourceList(roomName string, mediaResource map[string]*RoomMediaResource) string {
   382  	c.Lock(roomName)
   383  	var mediaRsrcList = ""
   384  	var resources []string
   385  	resources = make([]string, 0)
   386  	for resource := range mediaResource {
   387  		resources = append(resources, resource)
   388  	}
   389  	sort.Strings(resources)
   390  	for _, resource := range resources {
   391  		mediaRsrcList += "<option value = \"" + resource + "\">" + mediaResource[resource].label + "\n"
   392  	}
   393  	c.Unlock(roomName)
   394  	return mediaRsrcList
   395  }
   396  
   397  // GetImageList returns a well-formatted "HTML combo" containing all images.
   398  func (c *CherryRooms) GetImageList(roomName string) string {
   399  	return c.getMediaResourceList(roomName, c.configs[roomName].images)
   400  }
   401  
   402  //func (c *CherryRooms) GetSoundList(room_name string) string {
   403  //    return c.getMediaResourceList(room_name, c.configs[room_name].sounds)
   404  //}
   405  
   406  // GetUsersList returns a well-formatted "HTML combo" containing all users connected on a room.
   407  func (c *CherryRooms) GetUsersList(roomName string) string {
   408  	c.Lock(roomName)
   409  	var users []string
   410  	users = make([]string, 0)
   411  	for user := range c.configs[roomName].users {
   412  		users = append(users, user)
   413  	}
   414  	//  WARN(Santiago): Already locked, we can acquire this piece of information directly... otherwise we got a deadlock.
   415  	allUsersAlias := c.configs[roomName].misc.allUsersAlias
   416  	var usersList = "<option value = \"" + allUsersAlias + "\">" + allUsersAlias + "\n"
   417  	sort.Strings(users)
   418  	for _, user := range users {
   419  		usersList += "<option value = \"" + user + "\">" + user + "\n"
   420  	}
   421  	c.Unlock(roomName)
   422  	return usersList
   423  }
   424  
   425  func (c *CherryRooms) getRoomTemplate(roomName, template string) string {
   426  	c.configs[roomName].mutex.Lock()
   427  	var data string
   428  	data = c.configs[roomName].templates[template]
   429  	c.configs[roomName].mutex.Unlock()
   430  	return data
   431  }
   432  
   433  // SetPublicDirectory sets the public directory for a room.
   434  func (c *CherryRooms) SetPublicDirectory(roomName, value string) {
   435  	c.Lock(roomName)
   436  	c.configs[roomName].misc.publicDirectory = value
   437  	c.Unlock(roomName)
   438  }
   439  
   440  // GetPublicDirectory spits the room's public directory.
   441  func (c *CherryRooms) GetPublicDirectory(roomName string) string {
   442  	c.Lock(roomName)
   443  	dirPath := c.configs[roomName].misc.publicDirectory
   444  	c.Unlock(roomName)
   445  	return dirPath
   446  }
   447  
   448  // GetTopTemplate spits the top template data.
   449  func (c *CherryRooms) GetTopTemplate(roomName string) string {
   450  	return c.getRoomTemplate(roomName, "top")
   451  }
   452  
   453  // GetBodyTemplate spits the body template data.
   454  func (c *CherryRooms) GetBodyTemplate(roomName string) string {
   455  	return c.getRoomTemplate(roomName, "body")
   456  }
   457  
   458  // GetBannerTemplate spits the banner template data.
   459  func (c *CherryRooms) GetBannerTemplate(roomName string) string {
   460  	return c.getRoomTemplate(roomName, "banner")
   461  }
   462  
   463  // GetHighlightTemplate spits the highlight template data.
   464  func (c *CherryRooms) GetHighlightTemplate(roomName string) string {
   465  	return c.getRoomTemplate(roomName, "highlight")
   466  }
   467  
   468  // GetEntranceTemplate spits the entrance template data.
   469  func (c *CherryRooms) GetEntranceTemplate(roomName string) string {
   470  	return c.getRoomTemplate(roomName, "entrance")
   471  }
   472  
   473  // GetExitTemplate spits the exit template data.
   474  func (c *CherryRooms) GetExitTemplate(roomName string) string {
   475  	return c.getRoomTemplate(roomName, "exit")
   476  }
   477  
   478  // GetNickclashTemplate spits the nickclash template data.
   479  func (c *CherryRooms) GetNickclashTemplate(roomName string) string {
   480  	return c.getRoomTemplate(roomName, "nickclash")
   481  }
   482  
   483  // GetSkeletonTemplate spits the skeleton template data.
   484  func (c *CherryRooms) GetSkeletonTemplate(roomName string) string {
   485  	return c.getRoomTemplate(roomName, "skeleton")
   486  }
   487  
   488  // GetBriefTemplate spits the brief template data.
   489  func (c *CherryRooms) GetBriefTemplate(roomName string) string {
   490  	return c.getRoomTemplate(roomName, "brief")
   491  }
   492  
   493  // GetFindResultsHeadTemplate spits the find template data (HEAD).
   494  func (c *CherryRooms) GetFindResultsHeadTemplate(roomName string) string {
   495  	return c.getRoomTemplate(roomName, "find-results-head")
   496  }
   497  
   498  // GetFindResultsBodyTemplate spits the find template data (BODY).
   499  func (c *CherryRooms) GetFindResultsBodyTemplate(roomName string) string {
   500  	return c.getRoomTemplate(roomName, "find-results-body")
   501  }
   502  
   503  // GetFindResultsTailTemplate spits the find template data (TAIL).
   504  func (c *CherryRooms) GetFindResultsTailTemplate(roomName string) string {
   505  	return c.getRoomTemplate(roomName, "find-results-tail")
   506  }
   507  
   508  // GetFindBotTemplate spits the find bot template data.
   509  func (c *CherryRooms) GetFindBotTemplate(roomName string) string {
   510  	return c.getRoomTemplate(roomName, "find-bot")
   511  }
   512  
   513  // GetLastPublicMessages spits the last public messages (well-formatted in HTML).
   514  func (c *CherryRooms) GetLastPublicMessages(roomName string) string {
   515  	if !c.HasRoom(roomName) {
   516  		return ""
   517  	}
   518  	var retval string
   519  	c.Lock(roomName)
   520  	msgs := c.configs[roomName].publicMessages
   521  	c.Unlock(roomName)
   522  	for _, m := range msgs {
   523  		retval += m
   524  	}
   525  	return retval
   526  }
   527  
   528  // AddPublicMessage adds a public message to the pool of public messages that will be used for the room brief's composing.
   529  func (c *CherryRooms) AddPublicMessage(roomName, message string) {
   530  	if !c.HasRoom(roomName) {
   531  		return
   532  	}
   533  	c.Lock(roomName)
   534  	if len(c.configs[roomName].publicMessages) == 10 {
   535  		c.configs[roomName].publicMessages = c.configs[roomName].publicMessages[1 : len(c.configs[roomName].publicMessages)-1]
   536  	}
   537  	c.configs[roomName].publicMessages = append(c.configs[roomName].publicMessages, message)
   538  	c.Unlock(roomName)
   539  }
   540  
   541  // GetListenPort returns the port that is being used for the room serving.
   542  func (c *CherryRooms) GetListenPort(roomName string) string {
   543  	c.configs[roomName].mutex.Lock()
   544  	var port string
   545  	port = fmt.Sprintf("%d", c.configs[roomName].misc.listenPort)
   546  	c.configs[roomName].mutex.Unlock()
   547  	return port
   548  }
   549  
   550  // GetUsersTotal returns the total of users currently talking in a room.
   551  func (c *CherryRooms) GetUsersTotal(roomName string) string {
   552  	c.configs[roomName].mutex.Lock()
   553  	var total string
   554  	total = fmt.Sprintf("%d", len(c.configs[roomName].users))
   555  	c.configs[roomName].mutex.Unlock()
   556  	return total
   557  }
   558  
   559  // AddRoom adds a room to the "memory".
   560  func (c *CherryRooms) AddRoom(roomName string, listenPort int16) bool {
   561  	if c.HasRoom(roomName) || c.PortBusyByAnotherRoom(listenPort) {
   562  		return false
   563  	}
   564  	c.configs[roomName] = c.initConfig()
   565  	c.configs[roomName].misc.listenPort = listenPort
   566  	return true
   567  }
   568  
   569  // AddAction adds an action to the "memory".
   570  func (c *CherryRooms) AddAction(roomName, id, label, template string) {
   571  	c.configs[roomName].actions[id] = &RoomAction{label, template}
   572  }
   573  
   574  // AddImage adds an image (data that represents an image) to the "memory".
   575  func (c *CherryRooms) AddImage(roomName, id, label, template, url string) {
   576  	c.configs[roomName].images[id] = c.newMediaResource(label, template, url)
   577  }
   578  
   579  //func (c *CherryRooms) AddSound(room_name, id, label, template, url string) {
   580  //    c.configs[room_name].sounds[id] = c.newMediaResource(label, template, url)
   581  //}
   582  
   583  func (c *CherryRooms) newMediaResource(label, template, url string) *RoomMediaResource {
   584  	return &RoomMediaResource{label, template, url}
   585  }
   586  
   587  // HasAction verifies if an action really exists for the indicated room.
   588  func (c *CherryRooms) HasAction(roomName, id string) bool {
   589  	_, ok := c.configs[roomName].actions[id]
   590  	return ok
   591  }
   592  
   593  // HasImage verifies if an image really exists for the indicated room.
   594  func (c *CherryRooms) HasImage(roomName, id string) bool {
   595  	_, ok := c.configs[roomName].images[id]
   596  	return ok
   597  }
   598  
   599  //func (c *CherryRooms) HasSound(room_name, id string) bool {
   600  //    _, ok := c.configs[room_name].sounds[id]
   601  //    return ok
   602  //}
   603  
   604  // HasRoom verifies if a room really exists in this server.
   605  func (c *CherryRooms) HasRoom(roomName string) bool {
   606  	_, ok := c.configs[roomName]
   607  	return ok
   608  }
   609  
   610  // PortBusyByAnotherRoom verifies if there is some port clash between rooms.
   611  func (c *CherryRooms) PortBusyByAnotherRoom(port int16) bool {
   612  	for _, c := range c.configs {
   613  		if c.misc.listenPort == port {
   614  			return true
   615  		}
   616  	}
   617  	return false
   618  }
   619  
   620  // GetRoomByPort returns a room (all configuration from it) given a port.
   621  func (c *CherryRooms) GetRoomByPort(port int16) *RoomConfig {
   622  	for _, r := range c.configs {
   623  		if r.misc.listenPort == port {
   624  			return r
   625  		}
   626  	}
   627  	return nil
   628  }
   629  
   630  func (c *CherryRooms) initConfig() *RoomConfig {
   631  	var roomConfig *RoomConfig
   632  	roomConfig = new(RoomConfig)
   633  	roomConfig.misc = &RoomMisc{}
   634  	roomConfig.messageQueue = make([]Message, 0)
   635  	roomConfig.publicMessages = make([]string, 0)
   636  	roomConfig.users = make(map[string]*RoomUser)
   637  	roomConfig.templates = make(map[string]string)
   638  	roomConfig.actions = make(map[string]*RoomAction)
   639  	roomConfig.images = make(map[string]*RoomMediaResource)
   640  	//room_config.sounds = make(map[string]*RoomMediaResource)
   641  	roomConfig.mutex = new(sync.Mutex)
   642  	return roomConfig
   643  }
   644  
   645  // AddTemplate adds a template based on room name, ID.
   646  func (c *CherryRooms) AddTemplate(roomName, id, template string) {
   647  	c.configs[roomName].templates[id] = template
   648  }
   649  
   650  // HasTemplate verifies if a template really exists for a room.
   651  func (c *CherryRooms) HasTemplate(roomName, id string) bool {
   652  	_, ok := c.configs[roomName].templates[id]
   653  	return ok
   654  }
   655  
   656  // SetJoinMessage sets the join message.
   657  func (c *CherryRooms) SetJoinMessage(roomName, message string) {
   658  	c.configs[roomName].misc.joinMessage = message
   659  }
   660  
   661  // SetExitMessage sets the exit message.
   662  func (c *CherryRooms) SetExitMessage(roomName, message string) {
   663  	c.configs[roomName].misc.exitMessage = message
   664  }
   665  
   666  // SetOnIgnoreMessage sets the "on ignore" message.
   667  func (c *CherryRooms) SetOnIgnoreMessage(roomName, message string) {
   668  	c.configs[roomName].misc.onIgnoreMessage = message
   669  }
   670  
   671  // SetOnDeIgnoreMessage sets the "on deignore" message.
   672  func (c *CherryRooms) SetOnDeIgnoreMessage(roomName, message string) {
   673  	c.configs[roomName].misc.onDeIgnoreMessage = message
   674  }
   675  
   676  // SetGreetingMessage sets the greeting message.
   677  func (c *CherryRooms) SetGreetingMessage(roomName, message string) {
   678  	c.configs[roomName].misc.greetingMessage = message
   679  }
   680  
   681  // SetPrivateMessageMarker sets the private message marker.
   682  func (c *CherryRooms) SetPrivateMessageMarker(roomName, marker string) {
   683  	c.configs[roomName].misc.privateMessageMarker = marker
   684  }
   685  
   686  // SetMaxUsers sets the maximum of users allowed in a room.
   687  func (c *CherryRooms) SetMaxUsers(roomName string, value int) {
   688  	c.configs[roomName].misc.maxUsers = value
   689  }
   690  
   691  // SetAllowBrief sets the allow brief option.
   692  func (c *CherryRooms) SetAllowBrief(roomName string, value bool) {
   693  	c.configs[roomName].misc.allowBrief = value
   694  }
   695  
   696  // IsAllowingBriefs verifies if briefs are allowed for a room.
   697  func (c *CherryRooms) IsAllowingBriefs(roomName string) bool {
   698  	return c.configs[roomName].misc.allowBrief
   699  }
   700  
   701  //func (c *CherryRooms) SetFloodingPolice(roomName string, value bool) {
   702  //    c.configs[roomName].misc.floodingPolice = value
   703  //}
   704  
   705  //func (c *CherryRooms) SetMaxFloodAllowedBeforeKick(roomName string, value int) {
   706  //    c.configs[roomName].misc.maxFloodAllowedBeforeKick = value
   707  //}
   708  
   709  // SetAllUsersAlias sets all users alias.
   710  func (c *CherryRooms) SetAllUsersAlias(roomName, alias string) {
   711  	c.configs[roomName].misc.allUsersAlias = alias
   712  }
   713  
   714  // Lock acquire the room mutex.
   715  func (c *CherryRooms) Lock(roomName string) {
   716  	c.configs[roomName].mutex.Lock()
   717  }
   718  
   719  // Unlock dispose the room mutex.
   720  func (c *CherryRooms) Unlock(roomName string) {
   721  	c.configs[roomName].mutex.Unlock()
   722  }
   723  
   724  // GetServername spits the server name.
   725  func (c *CherryRooms) GetServername() string {
   726  	return c.servername
   727  }
   728  
   729  // SetServername sets the server name.
   730  func (c *CherryRooms) SetServername(servername string) {
   731  	c.servername = servername
   732  }
   733  
   734  // HasUser verifies if the user is connected in the room.
   735  func (c *CherryRooms) HasUser(roomName, user string) bool {
   736  	_, ok := c.configs[roomName]
   737  	if !ok {
   738  		return false
   739  	}
   740  	_, ok = c.configs[roomName].users[user]
   741  	return ok
   742  }
   743  
   744  // IsValidUserRequest verifies if the session ID really matches with the previously defined.
   745  func (c *CherryRooms) IsValidUserRequest(roomName, user, id string, userConn net.Conn) bool {
   746  	var valid = false
   747  	if c.HasUser(roomName, user) {
   748  		valid = (id == c.GetSessionID(user, roomName))
   749  		if valid {
   750  			c.Lock(roomName)
   751  			userAddr := strings.Split(userConn.RemoteAddr().String(), ":")
   752  			realAddr := c.configs[roomName].users[user].addr
   753  			c.Unlock(roomName)
   754  			if len(realAddr) > 0 && len(userAddr) > 0 {
   755  				valid = (realAddr == userAddr[0])
   756  			}
   757  		}
   758  	}
   759  	return valid
   760  }
   761  
   762  // SetIgnoreAction sets the action that will be used for ignoring.
   763  func (c *CherryRooms) SetIgnoreAction(roomName, action string) {
   764  	c.Lock(roomName)
   765  	c.configs[roomName].ignoreAction = action
   766  	c.Unlock(roomName)
   767  }
   768  
   769  // SetDeIgnoreAction sets the action that will be used for "deignoring".
   770  func (c *CherryRooms) SetDeIgnoreAction(roomName, action string) {
   771  	c.Lock(roomName)
   772  	c.configs[roomName].deignoreAction = action
   773  	c.Unlock(roomName)
   774  }
   775  
   776  // GetIgnoreAction returns the action that represents the ignoring.
   777  func (c *CherryRooms) GetIgnoreAction(roomName string) string {
   778  	c.Lock(roomName)
   779  	var retval string
   780  	retval = c.configs[roomName].ignoreAction
   781  	c.Unlock(roomName)
   782  	return retval
   783  }
   784  
   785  // GetDeIgnoreAction returns the action that represents the "deignoring".
   786  func (c *CherryRooms) GetDeIgnoreAction(roomName string) string {
   787  	c.Lock(roomName)
   788  	var retval string
   789  	retval = c.configs[roomName].deignoreAction
   790  	c.Unlock(roomName)
   791  	return retval
   792  }
   793  
   794  // SetUserConnection registers a connection for a user recently enrolled in a room.
   795  func (c *CherryRooms) SetUserConnection(roomName, user string, conn net.Conn) {
   796  	c.Lock(roomName)
   797  	c.configs[roomName].users[user].conn = conn
   798  	remoteAddr := strings.Split(conn.RemoteAddr().String(), ":")
   799  	if len(remoteAddr) > 0 {
   800  		c.configs[roomName].users[user].addr = remoteAddr[0]
   801  	}
   802  	c.Unlock(roomName)
   803  }
   804  
   805  // GetServerName spits the server name.
   806  func (c *CherryRooms) GetServerName() string {
   807  	return c.servername
   808  }
   809  
   810  // GetCertificatePath spits the certificate path.
   811  func (c *CherryRooms) GetCertificatePath() string {
   812  	return c.certPath
   813  }
   814  
   815  // GetPrivateKeyPath spits the private key path.
   816  func (c *CherryRooms) GetPrivateKeyPath() string {
   817  	return c.privKeyPath
   818  }
   819  
   820  // SetCertificatePath sets the certificate path.
   821  func (c *CherryRooms) SetCertificatePath(strPath string) {
   822  	c.certPath = strPath
   823  }
   824  
   825  // SetPrivateKeyPath sets the private key path.
   826  func (c *CherryRooms) SetPrivateKeyPath(strPath string) {
   827  	c.privKeyPath = strPath
   828  }