openfire插件开发入门——过滤脏话

↘锁芯ラ 提交于 2020-11-27 01:45:10

插件开发入门——过滤脏话

一、 简述

openfire为了扩展其他功能,适用于不同的需求,提供了插件的机制。

提前准备:把openfire源码导入到eclipse 或者 IDEA中。

二、说明

编写openfire插件,必须实现一个插件接口Plugin,只要实现了这个接口,就会被openfire认为是插件。

public interface Plugin {

    /**
     * Initializes the plugin.
     *
     * @param manager the plugin manager.
     * @param pluginDirectory the directory where the plugin is located.
     */
    void initializePlugin( PluginManager manager, File pluginDirectory );

    /**
     * Destroys the plugin.<p>
     *
     * Implementations of this method must release all resources held
     * by the plugin such as file handles, database or network connections,
     * and references to core Openfire classes. In other words, a
     * garbage collection executed after this method is called must be able
     * to clean up all plugin classes.
     */
    void destroyPlugin();

}

1. initializePlugin初始化插件

对数据库连接、rides等初始化。

2. destroyPlugin销毁插件

在这里必须释放所有用到的资源。

3. 插件启动

initializePlugin有三种情况会被调用,上传插件、重启插件、openfire启动时。

4. 插件目录结构

插件目录在:\src\plugins\下,一个插件一个目录。

举例:fastpath插件目录结构介绍

目录结构:

\src\plugins\fastpath
\src\plugins\fastpath\lib
\src\plugins\fastpath\src
\src\plugins\fastpath\logo_small.gif
\src\plugins\fastpath\logo_large.gif
\src\plugins\fastpath\changelog.html
\src\plugins\fastpath\plugin.xml
\src\plugins\fastpath\readme.html
  • lib:引用的jar包
  • src:src是源代码目录
  • logo_large.gif和logo_small.gif表示的是插件的logo,也支持png格式的文件,大小分别是32_32和16_16
  • changelog.html: 是发布日志,记录插件各个版本的变化情况。
  • plugin.xml:插件的配置文件。这个文件非常重要,openfire需要读取插件信息,例如插件的启动类是哪一个,需要在plugin.xml中定义
  • readme.html:插件的介绍和使用

三、编写过滤脏话插件

过滤脏话,就需要获取到消息内容,这个插件就要实现对数据包Packet拦截,必须要实现PacketInterceptor接口,这个接口就是包拦截器接口。

public interface PacketInterceptor {

    /**
     * Invokes the interceptor on the specified packet. The interceptor can either modify
     * the packet, or throw a PacketRejectedException to block it from being sent or processed
     * (when read).<p>
     *
     * An exception can only be thrown when <tt>processed</tt> is false which means that the read
     * packet has not been processed yet or the packet was not sent yet. If the exception is thrown
     * with a "read" packet then the sender of the packet will receive an answer with an error. But
     * if the exception is thrown with a "sent" packet then nothing will happen.<p>
     *
     * Note that for each packet, every interceptor will be called twice: once before processing
     * is complete (<tt>processing==true</tt>) and once after processing is complete. Typically,
     * an interceptor will want to ignore one or the other case.
     *
     * @param packet the packet to take action on.
     * @param session the session that received or is sending the packet.
     * @param incoming flag that indicates if the packet was read by the server or sent from
     *      the server.
     * @param processed flag that indicates if the action (read/send) was performed. (PRE vs. POST).
     * @throws PacketRejectedException if the packet should be prevented from being processed.
     */
    void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
            throws PacketRejectedException;
}

interceptPacket这个函数会在有packet传输到openfire的时候被调用。

1. 创建插件文件夹

仿照上面介绍的目录创建。添加src、plugin.xml等。

2. 将插件添加到Java Build Path中

创建了上面的文件夹,不添加到Java Build Path中是不能编译的。

3. 创建MessageFilterPlugin.java

package com.lwenhao;

import java.io.File;

import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.muc.MUCEventDispatcher;
import org.jivesoftware.openfire.muc.MUCEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.Message;

import com.group.action.GroupMessage;
import com.muc.interceptor.MUCEventListenerImpl;

/**
 * 插件的入口类,负责注入这个插件的功能
 * @author liuwenhao
 *
 */
public class MessageFilterPlugin implements Plugin, PacketInterceptor {
    // 拦截器管理器,所有的拦截器都在这里注册
    private InterceptorManager interceptorManager;

    // plugin的接口
    public void initializePlugin(PluginManager pManager, File pluginDirectory) {
        // InterceptorManager是一个单例类
        interceptorManager = InterceptorManager.getInstance();
        // 将拦截器注册进来,这样有Packet来的时候,就会调用interceptPacket
        interceptorManager.addInterceptor(this);
    }

    // plugin的接口    
    public void destroyPlugin() {
        // 插件卸载时,记得将拦截器从系统中移出。
        //当插件被卸载的时候,主要通过openfire管理控制台卸载插件时,被调用。
        //注意interceptorManager的addInterceptor和removeInterceptor需要成对调用。
        interceptorManager.removeInterceptor(this);
    }

    // PacketInterceptor的接口,包处理函数,对包的处理,在这里进行。
    public void interceptPacket(Packet packet, Session session, boolean read,
        boolean processed) throws PacketRejectedException {

            //processed为false,表示本条消息没有被openfire处理过。
            if (false == incoming && processed) {
                // packet可能是IQ、Presence、Message,这里当packet是message的时候,进行处理。
                if (packet instanceof Message) {
                    // 将packet强制转换为Message
                    Message msg = (Message)packet;
                    // 取得message中的body内容,就是消息正文
                    String body = msg.getBody();
                    // 如果内容中包含fuck,则拒绝处理消息
                    if(body != null  && body.contains("fuck")){
                        //这里通过抛出异常的方式,来阻止程序流程继续执行下去。
                        PacketRejectedException rejectedException =  new PacketRejectedException();

                        rejectedException.setRejectionMessage("fuck is error");

                        throw rejectedException;
                    }

                }
            }

    }
}

4. 创建或者修改plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <class>com.lwenhao.MessageFilterPlugin</class>
    <name>MessageFilterPlugin</name>
    <description>Message Filter Plugin</description>
    <author>liuwenhao</author>
    <version>0.0.1</version>
    <date>09/03/2018</date>
    <minServerVersion>4.2.2</minServerVersion>
</plugin>


class:插件的启动类
name:插件名称
description:描述
author:作者
version:版本
date:日期
minServerVersion:这个插件需要在openfire为4.2.2以上的版本运行

5.编译插件

\build\build.properties.template修改

#
# Directory where the jar files will be deployed (see the deployjar task)
#
deploy.jar.dir=
plugin = MessageFilterPlugin
#
# Directory where plugin development is done. This is assumed to be the
# root directory:
#
# /home/joeuser/java/myplugins/          <- Point to this directory
#                       |- fooplugin/
#                       |- barplugin/
#
plugin.dev.dir= MessageFilter

#
# Path to your Install4j installation. Typically this is c:\Program Files\install4j
# This property is set by default in the build.xml file as c:\Program Files\install4j so
# if you used the standard location you won't need to edit the property below.
#
# installer.install4j.home=

#
# Path to a bundled JRE you wish to use with the installer.rpm ant target
#
jre.bundle.location=

Eclipse->Window->Show View->Othre->Ant->Ant

双击 plugins编译插件,即可在目录\target\openfire\plugins中找到插件

6.运行插件

上传到openfire控制台就可以了

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!