添加派遣模块
This commit is contained in:
parent
645a4158ee
commit
a1e06f4687
@ -1,34 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"id": 101,
|
|
||||||
"quantity": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 102,
|
|
||||||
"quantity": 12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 103,
|
|
||||||
"quantity": 1000
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 104,
|
|
||||||
"quantity": 6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 105,
|
|
||||||
"quantity": 6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 106,
|
|
||||||
"quantity": 10012
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 107,
|
|
||||||
"quantity": 20
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 108,
|
|
||||||
"quantity": 2
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,28 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"num": [
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
3
|
|
||||||
],
|
|
||||||
"reward": [
|
|
||||||
{
|
|
||||||
"a": "attr",
|
|
||||||
"t": "gold",
|
|
||||||
"n": 999
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"a": "attr",
|
|
||||||
"t": "gold",
|
|
||||||
"n": 9999
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"a": "attr",
|
|
||||||
"t": "gold",
|
|
||||||
"n": 99999
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"day": 7
|
|
||||||
}
|
|
||||||
]
|
|
@ -34,53 +34,55 @@ const (
|
|||||||
|
|
||||||
// 模块名定义处
|
// 模块名定义处
|
||||||
const (
|
const (
|
||||||
ModuleSys core.M_Modules = "sys" //系统
|
ModuleSys core.M_Modules = "sys" //系统
|
||||||
ModuleGate core.M_Modules = "gateway" //gate模块 网关服务模块
|
ModuleGate core.M_Modules = "gateway" //gate模块 网关服务模块
|
||||||
ModuleWeb core.M_Modules = "web" //后台模块
|
ModuleWeb core.M_Modules = "web" //后台模块
|
||||||
ModuleUser core.M_Modules = "user" //用户模块
|
ModuleUser core.M_Modules = "user" //用户模块
|
||||||
ModulePack core.M_Modules = "pack" //背包模块
|
ModulePack core.M_Modules = "pack" //背包模块
|
||||||
ModuleMail core.M_Modules = "mail" //邮件模块
|
ModuleMail core.M_Modules = "mail" //邮件模块
|
||||||
ModuleFriend core.M_Modules = "friend" //好友模块
|
ModuleFriend core.M_Modules = "friend" //好友模块
|
||||||
ModuleMgoLog core.M_Modules = "mgolog" //日志模块
|
ModuleMgoLog core.M_Modules = "mgolog" //日志模块
|
||||||
ModuleEquipment core.M_Modules = "equipment" //装备模块
|
ModuleEquipment core.M_Modules = "equipment" //装备模块
|
||||||
ModuleHero core.M_Modules = "hero" //英雄模块
|
ModuleHero core.M_Modules = "hero" //英雄模块
|
||||||
ModuleForum core.M_Modules = "forum" //论坛模块
|
ModuleForum core.M_Modules = "forum" //论坛模块
|
||||||
ModuleItems core.M_Modules = "items" //道具模块
|
ModuleItems core.M_Modules = "items" //道具模块
|
||||||
ModuleShop core.M_Modules = "shop" //商店模块
|
ModuleShop core.M_Modules = "shop" //商店模块
|
||||||
ModuleTask core.M_Modules = "task" //任务模块
|
ModuleTask core.M_Modules = "task" //任务模块
|
||||||
ModuleMainline core.M_Modules = "mainline" //主线模块
|
ModuleMainline core.M_Modules = "mainline" //主线模块
|
||||||
ModuleNotify core.M_Modules = "notify" //公告模块
|
ModuleNotify core.M_Modules = "notify" //公告模块
|
||||||
ModuleChat core.M_Modules = "chat" //聊天模块
|
ModuleChat core.M_Modules = "chat" //聊天模块
|
||||||
ModuleGM core.M_Modules = "gm" //gm模块
|
ModuleGM core.M_Modules = "gm" //gm模块
|
||||||
ModulePagoda core.M_Modules = "pagoda" //魔塔模块
|
ModulePagoda core.M_Modules = "pagoda" //魔塔模块
|
||||||
ModuleMartialhall core.M_Modules = "martialhall" //武馆模块
|
ModuleMartialhall core.M_Modules = "martialhall" //武馆模块
|
||||||
ModuleGourmet core.M_Modules = "gourmet" //美食馆
|
ModuleGourmet core.M_Modules = "gourmet" //美食馆
|
||||||
ModuleRtask core.M_Modules = "rtask" //随机任务
|
ModuleRtask core.M_Modules = "rtask" //随机任务
|
||||||
ModuleSmithy core.M_Modules = "smithy" //铁匠铺
|
ModuleSmithy core.M_Modules = "smithy" //铁匠铺
|
||||||
ModuleTimer core.M_Modules = "timer" //定时任务模块
|
ModuleTimer core.M_Modules = "timer" //定时任务模块
|
||||||
ModuleViking core.M_Modules = "viking" //维京远征
|
ModuleViking core.M_Modules = "viking" //维京远征
|
||||||
ModuleMoonfantasy core.M_Modules = "moonfantasy" //月之秘境模块
|
ModuleMoonfantasy core.M_Modules = "moonfantasy" //月之秘境模块
|
||||||
ModuleHunting core.M_Modules = "hunting" //狩猎
|
ModuleHunting core.M_Modules = "hunting" //狩猎
|
||||||
ModuleLinestory core.M_Modules = "linestory" //支线剧情
|
ModuleLinestory core.M_Modules = "linestory" //支线剧情
|
||||||
ModuleBattle core.M_Modules = "battle" //战斗
|
ModuleBattle core.M_Modules = "battle" //战斗
|
||||||
ModuleLibrary core.M_Modules = "library" //藏书馆
|
ModuleLibrary core.M_Modules = "library" //藏书馆
|
||||||
ModuleArena core.M_Modules = "arena" //竞技场
|
ModuleArena core.M_Modules = "arena" //竞技场
|
||||||
ModuleTroll core.M_Modules = "troll" //巨怪商队
|
ModuleTroll core.M_Modules = "troll" //巨怪商队
|
||||||
ModuleHoroscope core.M_Modules = "horoscope" //星座图
|
ModuleHoroscope core.M_Modules = "horoscope" //星座图
|
||||||
ModuleSociaty core.M_Modules = "sociaty" //公会
|
ModuleSociaty core.M_Modules = "sociaty" //公会
|
||||||
ModulePay core.M_Modules = "pay" //支付
|
ModulePay core.M_Modules = "pay" //支付
|
||||||
ModuleAcademy core.M_Modules = "academy" //联盟学院
|
ModuleAcademy core.M_Modules = "academy" //联盟学院
|
||||||
ModulePrivilege core.M_Modules = "privilege" //特权
|
ModulePrivilege core.M_Modules = "privilege" //特权
|
||||||
ModuleGrowtask core.M_Modules = "growtask" //成长任务
|
ModuleGrowtask core.M_Modules = "growtask" //成长任务
|
||||||
ModuleWorldtask core.M_Modules = "worldtask" //世界任务
|
ModuleWorldtask core.M_Modules = "worldtask" //世界任务
|
||||||
ModuleReddot core.M_Modules = "reddot" //红点
|
ModuleReddot core.M_Modules = "reddot" //红点
|
||||||
ModuleCombat core.M_Modules = "combat" //关卡编辑
|
ModuleCombat core.M_Modules = "combat" //关卡编辑
|
||||||
ModuleEnchant core.M_Modules = "enchant" //附魔
|
ModuleEnchant core.M_Modules = "enchant" //附魔
|
||||||
ModuleAutoBattle core.M_Modules = "autobattle" //自动战斗
|
ModuleAutoBattle core.M_Modules = "autobattle" //自动战斗
|
||||||
ModuleMline core.M_Modules = "mline" //主线模块
|
ModuleMline core.M_Modules = "mline" //主线模块
|
||||||
ModulePvp core.M_Modules = "pvp" //实时pvp
|
ModulePvp core.M_Modules = "pvp" //实时pvp
|
||||||
ModulePractice core.M_Modules = "practice" //熊猫武馆 练功系统
|
ModulePandaTakekan core.M_Modules = "pandatakekan" //熊猫武馆
|
||||||
ModuleFitness core.M_Modules = "fitness" //熊猫武馆 每日一健
|
ModuleDispatch core.M_Modules = "dispatch" //武馆派遣
|
||||||
|
ModulePractice core.M_Modules = "practice" //熊猫武馆 练功系统
|
||||||
|
ModuleFitness core.M_Modules = "fitness" //熊猫武馆 每日一健
|
||||||
)
|
)
|
||||||
|
|
||||||
// 数据表名定义处
|
// 数据表名定义处
|
||||||
@ -233,6 +235,8 @@ const (
|
|||||||
|
|
||||||
///熊猫物管部
|
///熊猫物管部
|
||||||
TablePandata = "pandata"
|
TablePandata = "pandata"
|
||||||
|
// 熊猫武馆派遣
|
||||||
|
TableDispatch = "dispatch"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RPC服务接口定义处
|
// RPC服务接口定义处
|
||||||
|
17
modules/dispatch/api.go
Normal file
17
modules/dispatch/api.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package dispatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/modules"
|
||||||
|
)
|
||||||
|
|
||||||
|
type apiComp struct {
|
||||||
|
modules.MCompGate
|
||||||
|
module *Dispatch
|
||||||
|
}
|
||||||
|
|
||||||
|
func(this *apiComp) Init(service core.IService, module core.IModule,comp core.IModuleComp, options core.IModuleOptions) (err error){
|
||||||
|
_ = this.MCompGate.Init(service, module, comp, options)
|
||||||
|
this.module = module.(*Dispatch)
|
||||||
|
return
|
||||||
|
}
|
28
modules/dispatch/model_dispatch.go
Normal file
28
modules/dispatch/model_dispatch.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package dispatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/comm"
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/modules"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/x/bsonx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type modelDispatch struct {
|
||||||
|
modules.MCompModel
|
||||||
|
module *Dispatch
|
||||||
|
service core.IService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *modelDispatch) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
||||||
|
err = this.MCompModel.Init(service, module, comp, options)
|
||||||
|
this.TableName = comm.TableDispatch
|
||||||
|
this.module = module.(*Dispatch)
|
||||||
|
this.service = service
|
||||||
|
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
||||||
|
Keys: bsonx.Doc{{Key: "_id", Value: bsonx.Int32(1)}},
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
27
modules/dispatch/module.go
Normal file
27
modules/dispatch/module.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package dispatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go_dreamfactory/comm"
|
||||||
|
"go_dreamfactory/lego/core"
|
||||||
|
"go_dreamfactory/modules"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 派遣
|
||||||
|
type Dispatch struct {
|
||||||
|
modules.ModuleBase
|
||||||
|
api *apiComp
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewModule() core.IModule {
|
||||||
|
return &Dispatch{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Dispatch) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error){
|
||||||
|
err = this.ModuleBase.Init(service, module, options)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (this *Dispatch) GetType() core.M_Modules {
|
||||||
|
return comm.ModuleDispatch
|
||||||
|
}
|
@ -8,6 +8,7 @@ import (
|
|||||||
"go_dreamfactory/modules/battle"
|
"go_dreamfactory/modules/battle"
|
||||||
"go_dreamfactory/modules/chat"
|
"go_dreamfactory/modules/chat"
|
||||||
"go_dreamfactory/modules/combat"
|
"go_dreamfactory/modules/combat"
|
||||||
|
"go_dreamfactory/modules/dispatch"
|
||||||
"go_dreamfactory/modules/enchant"
|
"go_dreamfactory/modules/enchant"
|
||||||
"go_dreamfactory/modules/equipment"
|
"go_dreamfactory/modules/equipment"
|
||||||
"go_dreamfactory/modules/forum"
|
"go_dreamfactory/modules/forum"
|
||||||
@ -112,6 +113,7 @@ func main() {
|
|||||||
enchant.NewModule(),
|
enchant.NewModule(),
|
||||||
mline.NewModule(),
|
mline.NewModule(),
|
||||||
pvp.NewModule(),
|
pvp.NewModule(),
|
||||||
|
dispatch.NewModule(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <auto-generated>
|
|
||||||
// This code was generated by a tool.
|
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
// the code is regenerated.
|
|
||||||
// </auto-generated>
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
package cfg
|
|
||||||
|
|
||||||
type GameDispatch_All struct {
|
|
||||||
_dataMap map[int32]*GameDispatch_AllData
|
|
||||||
_dataList []*GameDispatch_AllData
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGameDispatch_All(_buf []map[string]interface{}) (*GameDispatch_All, error) {
|
|
||||||
_dataList := make([]*GameDispatch_AllData, 0, len(_buf))
|
|
||||||
dataMap := make(map[int32]*GameDispatch_AllData)
|
|
||||||
for _, _ele_ := range _buf {
|
|
||||||
if _v, err2 := DeserializeGameDispatch_AllData(_ele_); err2 != nil {
|
|
||||||
return nil, err2
|
|
||||||
} else {
|
|
||||||
_dataList = append(_dataList, _v)
|
|
||||||
dataMap[_v.Id] = _v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &GameDispatch_All{_dataList:_dataList, _dataMap:dataMap}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (table *GameDispatch_All) GetDataMap() map[int32]*GameDispatch_AllData {
|
|
||||||
return table._dataMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (table *GameDispatch_All) GetDataList() []*GameDispatch_AllData {
|
|
||||||
return table._dataList
|
|
||||||
}
|
|
||||||
|
|
||||||
func (table *GameDispatch_All) Get(key int32) *GameDispatch_AllData {
|
|
||||||
return table._dataMap[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <auto-generated>
|
|
||||||
// This code was generated by a tool.
|
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
// the code is regenerated.
|
|
||||||
// </auto-generated>
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
package cfg
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
type GameDispatch_AllData struct {
|
|
||||||
Id int32
|
|
||||||
Quantity float32
|
|
||||||
}
|
|
||||||
|
|
||||||
const TypeId_GameDispatch_AllData = 1167514754
|
|
||||||
|
|
||||||
func (*GameDispatch_AllData) GetTypeId() int32 {
|
|
||||||
return 1167514754
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_v *GameDispatch_AllData)Deserialize(_buf map[string]interface{}) (err error) {
|
|
||||||
{ var _ok_ bool; var _tempNum_ float64; if _tempNum_, _ok_ = _buf["id"].(float64); !_ok_ { err = errors.New("id error"); return }; _v.Id = int32(_tempNum_) }
|
|
||||||
{ var _ok_ bool; var _tempNum_ float64; if _tempNum_, _ok_ = _buf["quantity"].(float64); !_ok_ { err = errors.New("quantity error"); return }; _v.Quantity = float32(_tempNum_) }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeserializeGameDispatch_AllData(_buf map[string]interface{}) (*GameDispatch_AllData, error) {
|
|
||||||
v := &GameDispatch_AllData{}
|
|
||||||
if err := v.Deserialize(_buf); err == nil {
|
|
||||||
return v, nil
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <auto-generated>
|
|
||||||
// This code was generated by a tool.
|
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
// the code is regenerated.
|
|
||||||
// </auto-generated>
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
package cfg
|
|
||||||
|
|
||||||
type GameDispatch_Reward struct {
|
|
||||||
_dataMap map[int32]*GameDispatch_RewardData
|
|
||||||
_dataList []*GameDispatch_RewardData
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGameDispatch_Reward(_buf []map[string]interface{}) (*GameDispatch_Reward, error) {
|
|
||||||
_dataList := make([]*GameDispatch_RewardData, 0, len(_buf))
|
|
||||||
dataMap := make(map[int32]*GameDispatch_RewardData)
|
|
||||||
for _, _ele_ := range _buf {
|
|
||||||
if _v, err2 := DeserializeGameDispatch_RewardData(_ele_); err2 != nil {
|
|
||||||
return nil, err2
|
|
||||||
} else {
|
|
||||||
_dataList = append(_dataList, _v)
|
|
||||||
dataMap[_v.Id] = _v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &GameDispatch_Reward{_dataList:_dataList, _dataMap:dataMap}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (table *GameDispatch_Reward) GetDataMap() map[int32]*GameDispatch_RewardData {
|
|
||||||
return table._dataMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (table *GameDispatch_Reward) GetDataList() []*GameDispatch_RewardData {
|
|
||||||
return table._dataList
|
|
||||||
}
|
|
||||||
|
|
||||||
func (table *GameDispatch_Reward) Get(key int32) *GameDispatch_RewardData {
|
|
||||||
return table._dataMap[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <auto-generated>
|
|
||||||
// This code was generated by a tool.
|
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
|
||||||
// the code is regenerated.
|
|
||||||
// </auto-generated>
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
package cfg
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
type GameDispatch_RewardData struct {
|
|
||||||
Id int32
|
|
||||||
Num []int32
|
|
||||||
Reward []*Gameatn
|
|
||||||
Day int32
|
|
||||||
}
|
|
||||||
|
|
||||||
const TypeId_GameDispatch_RewardData = -356577150
|
|
||||||
|
|
||||||
func (*GameDispatch_RewardData) GetTypeId() int32 {
|
|
||||||
return -356577150
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_v *GameDispatch_RewardData)Deserialize(_buf map[string]interface{}) (err error) {
|
|
||||||
{ var _ok_ bool; var _tempNum_ float64; if _tempNum_, _ok_ = _buf["id"].(float64); !_ok_ { err = errors.New("id error"); return }; _v.Id = int32(_tempNum_) }
|
|
||||||
{
|
|
||||||
var _arr_ []interface{}
|
|
||||||
var _ok_ bool
|
|
||||||
if _arr_, _ok_ = _buf["num"].([]interface{}); !_ok_ { err = errors.New("num error"); return }
|
|
||||||
|
|
||||||
_v.Num = make([]int32, 0, len(_arr_))
|
|
||||||
|
|
||||||
for _, _e_ := range _arr_ {
|
|
||||||
var _list_v_ int32
|
|
||||||
{ var _ok_ bool; var _x_ float64; if _x_, _ok_ = _e_.(float64); !_ok_ { err = errors.New("_list_v_ error"); return }; _list_v_ = int32(_x_) }
|
|
||||||
_v.Num = append(_v.Num, _list_v_)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
var _arr_ []interface{}
|
|
||||||
var _ok_ bool
|
|
||||||
if _arr_, _ok_ = _buf["reward"].([]interface{}); !_ok_ { err = errors.New("reward error"); return }
|
|
||||||
|
|
||||||
_v.Reward = make([]*Gameatn, 0, len(_arr_))
|
|
||||||
|
|
||||||
for _, _e_ := range _arr_ {
|
|
||||||
var _list_v_ *Gameatn
|
|
||||||
{ var _ok_ bool; var _x_ map[string]interface{}; if _x_, _ok_ = _e_.(map[string]interface{}); !_ok_ { err = errors.New("_list_v_ error"); return }; if _list_v_, err = DeserializeGameatn(_x_); err != nil { return } }
|
|
||||||
_v.Reward = append(_v.Reward, _list_v_)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ var _ok_ bool; var _tempNum_ float64; if _tempNum_, _ok_ = _buf["day"].(float64); !_ok_ { err = errors.New("day error"); return }; _v.Day = int32(_tempNum_) }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeserializeGameDispatch_RewardData(_buf map[string]interface{}) (*GameDispatch_RewardData, error) {
|
|
||||||
v := &GameDispatch_RewardData{}
|
|
||||||
if err := v.Deserialize(_buf); err == nil {
|
|
||||||
return v, nil
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user