UE5 TPS开发p25 设置大厅,销毁会话,快速退出,检查按钮

这节课主要是完善了菜单选择地图作为游戏大厅,MultiPlayerSessionSubsystem的销毁会话函数,然后就是给Menu菜单添加了Quit和禁止使用按钮

同时还完善了创建房间的漏洞,因为在创建房间的时候如果退出后就马上加入就会发现自己无法创建房间,这是因为服务器判断房间销毁是有一定延迟的,所以这次使用委托来优化这一段逻辑

MultiPlayerSessionSubsystem.h

// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Subsystems/GameInstanceSubsystem.h" #include "Interfaces/OnlineSessionInterface.h" #include "MultiPlayerSessionSubsystem.generated.h" /** * 这里是我们自定义的委托 */ DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiPlayerOnCreateSessionComplete ,bool, bWasSuccessful); DECLARE_MULTICAST_DELEGATE_TwoParams(FMultiPlayerOnFindSessionComplete, const TArray<FOnlineSessionSearchResult>& SessionSearchResult , bool bWasSuccessful); DECLARE_MULTICAST_DELEGATE_OneParam(FMultiPlayerOnJoinSessionComplete, EOnJoinSessionCompleteResult::Type Result); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiPlayerOnDestroySessionComplete ,bool, bWasSuccessful); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiPlayerOnStartSessionComplete ,bool, bWasSuccessful); UCLASS() class UMultiPlayerSessionSubsystem : public UGameInstanceSubsystem { GENERATED_BODY() public: UMultiPlayerSessionSubsystem(); /* * 这里是一个句柄,让菜单类可以访问Subsystem */ void CreateSession(int32 NumPublicConnections,FString MatchType); void FindSession(int32 MaxSearchResults); void JoinSession(const FOnlineSessionSearchResult& SessionResults); void DestroySession(); void StartSession(); /* * 这是给菜单类做的回调委托 */ FMultiPlayerOnCreateSessionComplete MultiPlayerOnCreateSessionComplete; FMultiPlayerOnFindSessionComplete MultiPlayerOnFindSessionComplete; FMultiPlayerOnJoinSessionComplete MultiPlayerOnJoinSessionComplete; FMultiPlayerOnDestroySessionComplete MultiPlayerOnDestroySessionComplete; FMultiPlayerOnStartSessionComplete MultiPlayerOnStartSessionComplete; protected: /* * 这里是委托 */ void CreateSessionComplete(FName SessionName, bool bWasSuccessful); void FindSessionsComplete(bool bWasSuccessful); void JoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result); void DestroySessionComplete(FName SessionName, bool bWasSuccessful); void StartSessionComplete(FName SessionName, bool bWasSuccessful); private: //查找会话设置 TSharedPtr<FOnlineSessionSearch> LastSessionSearch; IOnlineSessionPtr OnlineSessionInterface; TSharedPtr<FOnlineSessionSettings> LastSessionSettings; /* * 添加OnlineSession委托到列表内 * 我们的游玩系统内部回调绑定到这里 * */ FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate; FDelegateHandle CreateSessionCompleteDelegate_Handle; FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate; FDelegateHandle FindSessionsCompleteDelegate_Handle; FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate; FDelegateHandle JoinSessionCompleteDelegate_Handle; FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate; FDelegateHandle DestroySessionCompleteDelegate_Handle; FOnStartSessionCompleteDelegate StartSessionCompleteDelegate; FDelegateHandle StartSessionCompleteDelegate_Handle; /*p25新增的三个变量,用来在退出游戏后想创建房间的时重新使用最后一次可用的设置*/ bool bCreateSessionOnDestroySession{false}; int32 LastNumPublicConnections; FString LastMatchType; };

MultiPlayerSessionSubsystem.cpp

// Fill out your copyright notice in the Description page of Project Settings. #include "MultiPlayerSessionSubsystem.h" #include "OnlineSessionSettings.h" #include "OnlineSubsystem.h" #include "Online/OnlineSessionNames.h" UMultiPlayerSessionSubsystem::UMultiPlayerSessionSubsystem(): CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this,&ThisClass::CreateSessionComplete)), FindSessionsCompleteDelegate(FOnFindSessionsCompleteDelegate::CreateUObject(this,&ThisClass::FindSessionsComplete)), JoinSessionCompleteDelegate(FOnJoinSessionCompleteDelegate::CreateUObject(this,&ThisClass::JoinSessionComplete)), DestroySessionCompleteDelegate(FOnDestroySessionCompleteDelegate::CreateUObject(this,&ThisClass::DestroySessionComplete)), StartSessionCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this,&ThisClass::StartSessionComplete)) { IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get(); if(OnlineSubsystem) { OnlineSessionInterface = OnlineSubsystem->GetSessionInterface(); } } void UMultiPlayerSessionSubsystem::CreateSession(int32 NumPublicConnections, FString MatchType) { if(!OnlineSessionInterface.IsValid()) { return; } auto ExistingSession = OnlineSessionInterface->GetNamedSession(NAME_GameSession); if(ExistingSession != nullptr) { /*检查上个房间是否关闭,如果指针不为空就调用关闭房间的委托*/ bCreateSessionOnDestroySession = true; LastNumPublicConnections = NumPublicConnections; LastMatchType = MatchType; DestroySession(); } //存放创建委托 CreateSessionCompleteDelegate_Handle = OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate); LastSessionSettings = MakeShareable(new FOnlineSessionSettings()); LastSessionSettings->bIsLANMatch = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true:false; //最多4人 LastSessionSettings->NumPublicConnections =NumPublicConnections; //允许其他玩家加入 LastSessionSettings->bAllowJoinInProgress = true; //允许好友加入 LastSessionSettings->bAllowJoinViaPresence = true; //线上公开 LastSessionSettings->bShouldAdvertise = true; //显示用户状态 LastSessionSettings->bUsesPresence = true; //使用第三方平台 LastSessionSettings->bUseLobbiesIfAvailable = true; //唯一标识符设置为整数1 LastSessionSettings->BuildUniqueId = 1; LastSessionSettings->Set(FName("MatchType"),MatchType,EOnlineDataAdvertisementType::ViaOnlineServiceAndPing); const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); if(OnlineSessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession , *LastSessionSettings)) { /*这里是创建失败*/ OnlineSessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate_Handle); /*在这里广播*/ MultiPlayerOnCreateSessionComplete.Broadcast(false); } } void UMultiPlayerSessionSubsystem::FindSession(int32 MaxSearchResults) { if(!OnlineSessionInterface.IsValid()) { return; } //这里将我们的委托设置成SessionInterface的句柄使用 FindSessionsCompleteDelegate_Handle = OnlineSessionInterface->AddOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate); //添加查询委托 OnlineSessionInterface->AddOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate); //设置查找 LastSessionSearch = MakeShareable(new FOnlineSessionSearch()); LastSessionSearch->MaxSearchResults = 10000; LastSessionSearch->bIsLanQuery= LastSessionSettings->bIsLANMatch = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true:false; //设置查询设置 LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE,true,EOnlineComparisonOp::Equals); //获得本地的第一个玩家 const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); //使用本地的第一个玩家的URL和查找设置进行查找,当查找为false或者空的时候删除句柄 if(!OnlineSessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(),LastSessionSearch.ToSharedRef())) { //删除掉句柄 OnlineSessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate_Handle); MultiPlayerOnFindSessionComplete.Broadcast(TArray<FOnlineSessionSearchResult>(),false); } } void UMultiPlayerSessionSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionResults) { if(!OnlineSessionInterface.IsValid()) { MultiPlayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError); return; } JoinSessionCompleteDelegate_Handle = OnlineSessionInterface->AddOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate); //获得本地的第一个玩家 const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); //调用JoinSession,并且加入的时候调用OnJoinSessionCompleteDelegate这个委托 if(!OnlineSessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),NAME_GameSession,SessionResults)) { MultiPlayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError); } } void UMultiPlayerSessionSubsystem::DestroySession() { /*检查在线会话接口是否有效*/ if(!OnlineSessionInterface.IsValid()) { MultiPlayerOnDestroySessionComplete.Broadcast(false); return; } DestroySessionCompleteDelegate_Handle = OnlineSessionInterface->AddOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegate); if(!OnlineSessionInterface->DestroySession(NAME_GameSession)) { OnlineSessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegate_Handle); MultiPlayerOnDestroySessionComplete.Broadcast(false); } } void UMultiPlayerSessionSubsystem::StartSession() { } void UMultiPlayerSessionSubsystem::CreateSessionComplete(FName SessionName, bool bWasSuccessful) { /*当成功创建房间的时候,删除创建房间的句柄*/ if(OnlineSessionInterface) { OnlineSessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate_Handle); } MultiPlayerOnCreateSessionComplete.Broadcast(bWasSuccessful); } void UMultiPlayerSessionSubsystem::FindSessionsComplete(bool bWasSuccessful) { if(OnlineSessionInterface) { OnlineSessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate_Handle); } if(LastSessionSearch->SearchResults.Num()<=0) { //找到了玩家后删除掉句柄 OnlineSessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate_Handle); return; } MultiPlayerOnFindSessionComplete.Broadcast(LastSessionSearch->SearchResults,bWasSuccessful); } void UMultiPlayerSessionSubsystem::JoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result) { if(OnlineSessionInterface) { OnlineSessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate_Handle); } MultiPlayerOnJoinSessionComplete.Broadcast(Result); } void UMultiPlayerSessionSubsystem::DestroySessionComplete(FName SessionName, bool bWasSuccessful) { if(OnlineSessionInterface) { OnlineSessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegate_Handle); } /*当bWasSusscful是true的时候,返回委托并创建房间,使用最后一次使用的参数*/ if(bWasSuccessful && bCreateSessionOnDestroySession) { bCreateSessionOnDestroySession = false; CreateSession(LastNumPublicConnections,LastMatchType); } MultiPlayerOnDestroySessionComplete.Broadcast(bWasSuccessful); } void UMultiPlayerSessionSubsystem::StartSessionComplete(FName SessionName, bool bWasSuccessful) { }

BaseMenu.h

// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include "Interfaces/OnlineSessionInterface.h" #include "BaseMenu.generated.h" /** * */ class UButton; UCLASS() class MULTIPLAYERSESSION_API UBaseMenu : public UUserWidget { GENERATED_BODY() protected: virtual bool Initialize() override; virtual void NativeDestruct() override; /*这里创建用来对应MultiPlayerOnCreateSessionComplete的函数*/ UFUNCTION() void OnCreateSession(bool bWasSuccessful); void OnFindSession(const TArray<FOnlineSessionSearchResult>& SessionSearchResult , bool bWasSuccessful); void OnJoinSession(EOnJoinSessionCompleteResult::Type Result); UFUNCTION() void OnDestroySession(bool bWasSuccessful); UFUNCTION() void OnStartSession(bool bWasSuccessful); public: /*菜单初始化*/ UFUNCTION(BlueprintCallable) void MenuSetup(int SetupNumPublicConnections = 4,FString SetupMatchType = TEXT("FreeForAll") , FString LobbyPath = FString(TEXT("/Game/ThirdPerson/Maps/Lobby"))); void _DebugLog(FColor DisplayColor, const FString& DebugMessage); private: //将指针与按钮绑定起来,这里的绑定必须要指针变量名称和UMG的名称完全一样 UPROPERTY(meta=(BindWidget)) UButton* HostButton; UPROPERTY(meta=(BindWidget)) UButton* JoinButton; UFUNCTION() void HostButtonClicked(); UFUNCTION() void JoinButtonClincked(); UFUNCTION() void MenuTearDown(); class UMultiPlayerSessionSubsystem* MultiPlayerSessionSubsystem; int32 NumPublicConnections{4}; FString MatchType{TEXT("FreeForAll")}; FString PathToLobby{TEXT("")}; };

BaseMenu.cpp

// Fill out your copyright notice in the Description page of Project Settings. #include "BaseMenu.h" #include "OnlineSessionSettings.h" #include "MultiPlayerSession/Public/MultiPlayerSessionSubsystem.h" #include "Components/Button.h" bool UBaseMenu::Initialize() { if(!Super::Initialize()) { return false; } if(HostButton) { HostButton->OnClicked.AddDynamic(this,&UBaseMenu::HostButtonClicked); } if(JoinButton) { JoinButton->OnClicked.AddDynamic(this,&UBaseMenu::JoinButtonClincked); } return true; } void UBaseMenu::NativeDestruct() { Super::NativeDestruct(); } void UBaseMenu::MenuSetup(int SetupNumPublicConnections ,FString SetupMatchType , FString LobbyPath) { PathToLobby = FString::Printf(TEXT("%s?listen"),*LobbyPath); NumPublicConnections = SetupNumPublicConnections; MatchType = SetupMatchType; AddToViewport(); SetVisibility(ESlateVisibility::Visible); bIsFocusable = true; UWorld* World = GetWorld(); if(World) { APlayerController* PlayerController = World->GetFirstPlayerController(); if(PlayerController) { FInputModeUIOnly InputModeUIOnly; InputModeUIOnly.SetWidgetToFocus(TakeWidget()); InputModeUIOnly.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); PlayerController->SetInputMode(InputModeUIOnly); PlayerController->SetShowMouseCursor(true); } } UGameInstance* GameInstance = GetGameInstance(); if(GameInstance) { MultiPlayerSessionSubsystem = GameInstance->GetSubsystem<UMultiPlayerSessionSubsystem>(); } if(MultiPlayerSessionSubsystem) { MultiPlayerSessionSubsystem->MultiPlayerOnCreateSessionComplete.AddDynamic(this,&ThisClass::OnCreateSession); /*当委托是静态的时候需要使用 AddUObject */ MultiPlayerSessionSubsystem->MultiPlayerOnFindSessionComplete.AddUObject(this,&ThisClass::OnFindSession); MultiPlayerSessionSubsystem->MultiPlayerOnJoinSessionComplete.AddUObject(this,&ThisClass::OnJoinSession); MultiPlayerSessionSubsystem->MultiPlayerOnDestroySessionComplete.AddDynamic(this,&ThisClass::OnDestroySession); MultiPlayerSessionSubsystem->MultiPlayerOnStartSessionComplete.AddDynamic(this,&ThisClass::OnStartSession); } } void UBaseMenu::OnCreateSession(bool bWasSuccessful) { if(bWasSuccessful) { _DebugLog(FColor::Green,TEXT("CreateSession Successful")); } else { UWorld* World = GetWorld(); if(World) { World->ServerTravel(PathToLobby); } else { HostButton->SetIsEnabled(true); } } } void UBaseMenu::OnFindSession(const TArray<FOnlineSessionSearchResult>& SessionSearchResult, bool bWasSuccessful) { if(MultiPlayerSessionSubsystem==nullptr) { return; } for(auto Result : SessionSearchResult) { FString SettingValue; Result.Session.SessionSettings.Get(FName("MatchType"),SettingValue); if(SettingValue == MatchType) { MultiPlayerSessionSubsystem->JoinSession(Result); return; } } if(!bWasSuccessful || SessionSearchResult.Num() == 0) { JoinButton->SetIsEnabled(true); } } void UBaseMenu::OnJoinSession(EOnJoinSessionCompleteResult::Type Result) { //加入游戏 IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get(); if(OnlineSubsystem) { IOnlineSessionPtr OnlineSessionInterface = OnlineSubsystem->GetSessionInterface(); if(OnlineSessionInterface.IsValid()) { FString Address; if(OnlineSessionInterface->GetResolvedConnectString(NAME_GameSession,Address)) { APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController(); if(PlayerController) { PlayerController->ClientTravel(Address,ETravelType::TRAVEL_Absolute); } } } } if(Result != EOnJoinSessionCompleteResult::Success) { JoinButton->SetIsEnabled(true); } } void UBaseMenu::OnDestroySession(bool bWasSuccessful) { } void UBaseMenu::OnStartSession(bool bWasSuccessful) { } void UBaseMenu::_DebugLog(FColor DisplayColor, const FString& DebugMessage) { if(GEngine) { GEngine->AddOnScreenDebugMessage(-1,15.f,DisplayColor,DebugMessage); } } void UBaseMenu::HostButtonClicked() { HostButton->SetIsEnabled(false); if(MultiPlayerSessionSubsystem) { MultiPlayerSessionSubsystem->CreateSession(NumPublicConnections,MatchType); } _DebugLog(FColor::Blue,FString::Printf(TEXT("Create Session Success"))); } void UBaseMenu::JoinButtonClincked() { //点击加入按钮 JoinButton->SetIsEnabled(false); if(MultiPlayerSessionSubsystem) { MultiPlayerSessionSubsystem->FindSession(10000); } } void UBaseMenu::MenuTearDown() { UWorld* World = GetWorld(); RemoveFromParent(); APlayerController* PlayerController = World->GetFirstPlayerController(); FInputModeGameAndUI InputModeGameAndUI; PlayerController->SetInputMode(InputModeGameAndUI); PlayerController->SetShowMouseCursor(false); }

我们新建了一个在Maps文件夹下的StartingMap关卡

然后在第三人称地图内选择这个关卡作为加入关卡

在Menu内新增了Quit

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/758898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shell的介绍以及Linux权限的讲解

1 shell命令以及运行原理 1.1 shell命令行的概念 大家在以前的学习中可能会有一个固态的印象&#xff1a; 一台计算机的大概分层为下图 也就是说人可以直接调用计算机的操作系统&#xff0c;但真的是这样吗&#xff1f; 答案是否定的&#xff01; 其实操作系统还有一个“外壳…

31.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-其它消息的实现与使用优化

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;30.数据搜索功能…

如果QQ当年有AI,当年的经典头像会是什么样子?-WEBUI有趣案例分享

&#x1f454;背景介绍 IP_Adapter是个很有趣的模型&#xff0c;可以实现一定程度上的角色一致性&#xff0c;忽然有个想法&#xff0c;用IP_Adapter还原一下QQ当年的经典头像会是什么样子呢&#xff1f; 不过&#xff0c;大家还记得这些古早时期的头像吗&#xff1f;或者&…

优雅的 Markdown

Markdown浅尝 一、勾选框 注意[]前后都要有空格 - [x] 干的漂亮 - [x] 吃饭 - [x] 写代码 - [ ] 睡觉 干的漂亮 吃饭 写代码 睡觉 二、列表 #无序列列表 * 换成 - 也行 * 你 * 你好 * 你好呀 - 你很好啊 你你好你好呀你很好啊 #有序列表 . 后面有个空格 1. 我 2. 是我 3.…

Day73:WEB攻防-支付逻辑篇篡改属性值并发签约越权盗用算法溢出替换对冲

目录 SRC-支付逻辑测试 购买支付-修改数量&篡改价格&订单对冲 修改数量 篡改价格 产品替换对冲 订单替换对冲 购买支付-优惠券复用盗用&积分对冲溢出 优惠卷复用 优惠卷盗用 积分对冲溢出 SRC实战案例分享 越权让他人支付 四舍五入半价购 并发提前全…

python字典:打印字典中的键、值、打印所有字典、python遍历字典

1.定义 字典以花括号&#xff08;{}&#xff09;括起来&#xff0c;里面的元素是成对出现的&#xff0c;不同对元素用逗号&#xff08;,&#xff09;分开&#xff1b;一对元素用 冒号&#xff08;&#xff1a;&#xff09;分割。 2.解读 字典里的每一对元素准确的来说是键值对&…

javaSwing连连看

一、简介 基于java的连连看游戏设计和实现&#xff0c;基本功能包括&#xff1a;消除模块&#xff0c;重新开始模块&#xff0c;刷新模块&#xff0c;选择难度模块&#xff0c;计时模块。本系统结构如下&#xff1a; &#xff08;1&#xff09;消除模块&#xff1a; 完成连连…

python socket 实时通信,多对多,一对一,转发

研究一下python socket 实时通信&#xff0c;多对多&#xff0c;一对一&#xff0c;转发 C>S 单独通信 server1 import socket import threading# 在线客户端列表 online_clients {}def broadcast(message, sender):"""向所有在线客户端广播消息,除了发送…

面试算法-58-求根节点到叶节点数字之和

题目 给你一个二叉树的根节点 root &#xff0c;树中每个节点都存放有一个 0 到 9 之间的数字。 每条从根节点到叶节点的路径都代表一个数字&#xff1a; 例如&#xff0c;从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。 计算从根节点到叶节点生成的 所有数字之和…

2024年腾讯云优惠券全解析、云服务器代金券领取、查询和使用方法

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

Dockerfile Docker Compose(实战总结)

Dockerfile & Docker Compose&#xff08;实战总结&#xff09; Dockerfile Dockerfile 是用来构建Docker镜像文件&#xff0c;是由一条条构建镜像所需的指令构成的脚步。 步骤&#xff1a; 编写Dockerfile 文件docker build 构建镜像docker run 运行镜像docker push 发…

python coding with ChatGPT 打卡第23天| 回溯算法:理论基础

文章目录 视频讲解回溯法的效率解决的问题如何理解回溯法回溯框架 视频讲解 回溯算法理论篇 回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 回溯法的效率 回溯的本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案&#xff0c;如果想让回溯法…

区域规划(Regional Planning)的学习笔记

目录 一、概念题 1.区域的概念、类型、特性 2.区域分析的概念、主要内容 3.自然环境、自然资源的概念 4.区域自然资源评价的内容 5.可持续发展理论定义 6.经济增长、经济结构定义 7.产业结构概念 8.人口增长分析的含义、指标 9.技术进步概念、类型 10.技术进步对区域…

【C++ leetcode】双指针问题(续)

3. 202 .快乐数 题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结…

ArcGIS Pro、R和INVEST:三位一体的生态系统服务评估框架

生态系统服务是指生态系统所形成的用于维持人类赖以生存和发展的自然环境条件与效用&#xff0c;是人类直接或间接从生态系统中得到的各种惠益。联合国千年生态系统评估&#xff08;Millennium ecosystem assessment&#xff0c;MA&#xff09;提出生态系统服务包括供给、调节、…

智慧水务:雨季山区水域水务智能化监控与监测管理方案

一、方案背景 雨季的水务管理对于各区县来说&#xff0c;无疑是一项至关重要的任务。夏季雨水充沛&#xff0c;江河湖泊水位上涨&#xff0c;山洪、上游排水等情况时有发生&#xff0c;给各地的水务设施和防汛工作带来了严峻的挑战。针对区县的各类水域监管场景&#xff0c;需…

免费的chatgpt网站(包含最新版4.0)

相信每个人在生活工作学习中都逃不过用chatgpt来解决一些问题&#xff0c;下面我长话短说&#xff0c;为大家简单介绍几款免费且好用的chatgpt网站 1、YesChat 网址&#xff1a;YesChat-ChatGPT4V Dalle3 Claude 3 All in One Free 第一个就给大家介绍一个狠角色&#xff0c;最…

C 语言中位取反操作符 ~ 和逻辑取反操作符 !

在 C 语言中&#xff0c;有两种取反操作符&#xff0c;分别是位取反操作符 ~ 和逻辑取反操作符 !。 位取反操作符 ~&#xff1a; 位取反操作符 ~ 是一个一元操作符&#xff0c;用于执行按位取反操作。它会将操作数的每个位取反&#xff0c;即将 0 变为 1&#xff0c;将 1 变为 …

算法打卡day21|回溯法篇01|理论知识,Leetcode 77.组合

回溯法理论知识 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。回溯是递归的副产品&#xff0c;只要有递归就会有回溯。所以回溯函数也就是递归函数&#xff0c;指的都是一个函数。 回溯法的效率 回溯法并不是什么高效的算法。因为回溯的本质是穷举&#xff0c;…

win提权第二弹服务提权

阅读须知&#xff1a; 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者 本人负责&#xff0c;作者不为此承担任何责任,如…